Today アクセスカウンター Yesterday アクセスカウンター

最近ダレ気味

どんどん生活が夜型に… 私は,夜になると意味も無く死にたくなるというわけがわからない精神構造の人間なので,これは非常に由々しき事態.

do {

夜がふける ; 研究に疲れてくる ; 人生に疲れてくる ; いろいろつらくなる ; 酒浸り ; 意味も無く廃テンション ; 無意味に遅くまで起きてる ; 朝起きれない ; 起きれなくて,朝から自己嫌悪 ; やる気がなくなる ; 東京とかに比べればぜんぜんとはいえ,暑い ; ますますやる気がなくなる ; 無意味に遅くまで研究室にいる ; 夜が更ける ; 研究が進まない ; 将来に対する漠然とした不安 ; 一向に消化されないレポートの山 ; ゲンナリ ; 現実逃避 ; ますますやる気が無くなる ; 気力,体力が消耗 ; 無意味に深夜

} while(true);

まぁ,酒は良くないよね.

すべての原因は研究が進まないことにあるのだ.

あーあー,研究なんて,凡人がするもんじゃないな.僕は深夜のコンビニでレジ打ったりしてだらだら生きていくべきだと思った.

みんなに喜ばれる,素敵な森のパン屋さんになりたいなぁ… ケーキを焼いたり,クッキーを焼いたり.お客さんはクマさんウサギさんとか.

… 朝早いから無理だろうなぁ (駄目)




人間止めますか,現実逃避ダメ絶対.

まぁ,私のコードジェネレーションが死ぬほど適当なのが悪い自業自得なんですが,コンパイラのバグが取れなくて困ってます.そりゃあ全てを投げ出して,盗んだバイクで走り出したくもなりますよ.

append とか factorial あたりの簡単なルールは,もう大方コンパイルして dll 作って S 式 (クエリー) を読み込むインタフェースから起動できるようになってきたので,今は n 番目の素数を求める nthprime とか,ちょっと複雑なやつをコンパイルできるようにしています.かなり行き当たりばったりに作っているので,いろいろ無理が出てきてますが.

# リファクタリング (テストが怪しいので,おこがましい言い方ですが) している間は表面上は何も進んでないように見えるため,進捗報告がいろいろ苦しくなってイヤーンな感じになりますし… とりあえず nthprime が動いたら,いろいろ綺麗にしていきたい.これでもだいぶがんばってるのですが.

(アカデミックな人って,みんな無意味に素数生成大好きだよね ☆)

コンパイルする D ルールは,こんな感じ.

(nthprime *1 *A), {(== *1 1)}
--> (= *A 2).
(nthprime *B *C)
--> (createArray *D *B),
(setArrayElement *D 0 2),
(primeArray 3 *D 0 1 *B),
(:= *E (- *B 1)),
(getArrayElement *D *E *C),
(DestroyArray *D).

(DestroyArray *D) --> (print *D).

(primeArray *F *G *H *I *J), {(== *I *J)} -->.

(primeArray *K *L *M *N *O),
{(getArrayElement *L *M *P),
(:= *Q (x *P *P)),
(< *K *Q)}
--> (setArrayElement *L *N *K),
(:= *R (+ *N 1)),
(:= *S (+ *K 2)),
(primeArray *S *L 1 *R *O).

(primeArray *T *A *i *W *X),
{(getArrayElement *A *i *Y),
(:= 0 (mod *T *Y))}
--> (:= *A1 (+ *T 2)),
(primeArray *A1 *A 1 *W *X).

(primeArray *B1 *A *i *E1 *F1)
--> (getArrayElement *A *i *G1),
(:= *i1 (+ *i 1)),
(primeArray *B1 *A *i1 *E1 *F1).


まぁ,この D ルールは私が書いたものじゃないので,実はよくわからないところが何箇所かあるのですが.

明らかに不要な命令とかあったし.なんか,微妙に変換器を意識したのか,手続き型言語っぽい感じになってるし.わざわざヘッドでのパターンマッチを使わないでいるところとか.DestroyArray とかは,ETI のレベルでは不要 (GC されるから) なので,配列を表示させたりと,どうでも良いようなことしてます.

おそらく,何らかの変換器を通ったものなのでしょう.変数名とかが機械的に A1 F1 E1 とか振られていて,分かり難いですが,まぁこの程度なら何とか (ちょこっと中途半端に書き直していたりもしますが).

しかしまぁ,別に人間がこれ書き換えたりするわけではないので,問題無しと.単なる例題ですので.

一応動かしてみると,

[D]>(nthprime 10 *)
-------------------------D execution ---------------------
{2 3 5 7 11 13 17 19 23 29}
----------------------------------------------------------
succeeded.
(nthprime 10 29)

ちゃんと動いてるっぽいですね.

要は,配列に順番に素数を詰めていって,比較しつつ探索を進めていく感じ.

まぁ,これをまたテキトーに何段階かプログラム変換すると (初期の方には,私はかかわってないので,途中までブラックボックスです).

?- (include "runtime.eti").

(as (main (nthprime *A *B))
:
(makeStack *C)
(makeHeap *D)
(setArgs 1 (*A *B) 2 *C *D)
(saveStack *C *E)
(nthprime2 *C *D)
(returnArgs 1 (*A *B) 2 *E *D))

(as (nthprime2 *G *H)
(getArrayElement *G 1 *F)
:
(dec ((arr 3)) *F *G *H)
(nthprime21 *G *H))

(as (nthprime21 *C *D)
(getArrayElement *C 1 *I)
(not (== 1 (INT 1) *I *C *D))
:
(nthprime22 *C *D))

(as (nthprime21 *C *D)
(getArrayElement *C 1 *I)
:
(makeSexp 2 2 *I *C *D)
(return TRUE *I *C *D))

(as (nthprime22 *C *D)
(getArrayElement *C 1 *I)
:
(eval (newpvar 3) *I *C *D *J)
(createArray *J 1 *I *C *D)
//(print (createArray *J 1 *I *C *D))
(setArrayElement 3 (INT 0) (INT 2) *I *C *D)
//(print (setArrayElement 3 (INT 0) (INT 2) *I *C *D))
(subst s 1 (INT 3) *I *C *D)
(subst s 2 3 *I *C *D)
(subst s 3 (INT 0) *I *C *D)
(subst s 4 (INT 1) *I *C *D)
(subst s 5 1 *I *C *D)
(--call (primeArray5 5 *C *D))
(eval (- 1 (INT 1)) *I *C *D *K)
(getArrayElement 3 *K 2 *I *C *D)
(return TRUE *I *C *D))
/*
(as (main (primeArray *L *M *N *O *P))
:
(makeStack primeArray *C)
(makeHeap *D)
(setArgs 1 (*L *M *N *O *P) 2 *C *D)
(saveStack *C *Q)
(primeArray5 *C *D)
(returnArgs 1 (*L *M *N *O *P) 2 *Q *D))
*/
(as (primeArray5 *S *T)
(getArrayElement *S 1 *R)
:
(dec ((char 6)) *R *S *T)
(primeArray51 *S *T))

(as (primeArray51 *C *D)
(getArrayElement *C 1 *I)
(not (== 4 5 *I *C *D))
:
(primeArray52 *C *D))

(as (primeArray51 *C *D)
(getArrayElement *C 1 *I)
:
(return TRUE *I *C *D))

(as (primeArray52 *C *D)
(getArrayElement *C 1 *I)
(eval (newpvar 6) *I *C *D *U)
(getArrayElement 2 3 *U *I *C *D)
(eval (x 6 6) *I *C *D *V)
(not (< 1 *V *I *C *D))
:
(primeArray53 *C *D))

(as (primeArray52 *C *D)
(getArrayElement *C 1 *I)
:
(setArrayElement 2 4 1 *I *C *D)
(eval (+ 4 (INT 1)) *I *C *D *W)
(subst t 4 *W *I *C *D)
(subst t 3 (INT 1) *I *C *D)
(eval (+ 1 (INT 2)) *I *C *D *X)
(subst t 1 *X *I *C *D)
(primeArray51 *C *D))

(as (primeArray53 *C *D)
(getArrayElement *C 1 *I)
(eval (newpvar 6) *I *C *D *Y)
(getArrayElement 2 3 *Y *I *C *D)
(eval (mod 1 6) *I *C *D *A1)
(not (== (INT 0) *A1 *I *C *D))
:
(primeArray54 *C *D))

(as (primeArray53 *C *D)
(getArrayElement *C 1 *I)
:
(subst t 3 (INT 1) *I *C *D)
(eval (+ 1 (INT 2)) *I *C *D *B1)
(subst t 1 *B1 *I *C *D)
(primeArray51 *C *D))

(as (primeArray54 *C *D)
(getArrayElement *C 1 *I)
:
(eval (+ 3 (INT 1)) *I *C *D *C1)
(subst t 3 *C1 *I *C *D)
(primeArray51 *C *D))

こーんな感じで,かなり手続き型言語チックに.この API というか変換のやり方とか形式のところ全般が,私が進めているところです.

なんか,デバッグのためのコードもコメントアウトされたまんまで混じっちゃってますが,気にしないでください.

runtime.eti ってのは,私がテキトーに書いた,ETI の上で上記のプログラムを動かすための,基本的な実行用ルールが定義されているファイルです.

main ってのは,ETI の上でのエントリーポイントです.コンパイルする際には無視されます.

んで,これを部分評価すると

[D]>(peval "nthprime.eti")
-------------------------D execution ---------------------
(as (main (nthprime *A *B)) :
(createArray *C 200)
(setArrayElement *C 2 2)
(setArrayElement *C 1 2)
(setArrayElement *C 0 2)
(createArray *D 300)
(setArrayElement *D 0 0)
(setSexp 1 *A 2 *C *D)
(setSexp 2 *B 2 *C *D)
(getArrayElement *C 0 *E)
(:= *F (+ *E 1))
(createArray *G *F)
(saveArray *F *C *G)
(nthprime2 *C *D)
(returnArg 1 *A 2 *G *D)
(returnArg 2 *B 2 *G *D))

(as (nthprime2 *H *I)
(getArrayElement *H 1 *J) :
(getArrayElement *I 0 *K)
(:= *L (+ *K 1))
(:= *M (+ *K 2))
(setArrayElement *I 0 *M)
(setArrayElement *I *L PVAR)
(:= *N (+ 3 *J))
(setArrayElement *H *N *L)
(updateArrayLength *N *H)
(nthprime21 *H *I))

(as (nthprime21 *O *P)
(getArrayElement *O 1 *Q)
(not (== 1 (INT 1) *Q *O *P)) :
(nthprime22 *O *P))

(as (nthprime21 *R *S)
(getArrayElement *R 1 *T) :
(:= *U (+ 2 *T))
(getArrayElement *R *U *V)
(setArrayElement *S *V INT)
(:= *W (+ *V 1))
(setArrayElement *S *W 2)
(getArrayElement *R *T *X)
(setArrayElement *R 1 *X)
(:= *Y (- *T 1))
(setArrayElement *R 0 *Y))

(as (nthprime22 *A1 *B1)
(getArrayElement *A1 1 *C1) :
(getArrayElement *B1 0 *D1)
(:= *E1 (+ *D1 1))
(:= *F1 (+ *D1 2))
(setArrayElement *B1 0 *F1)
(setArrayElement *B1 *E1 PVAR)
(:= *G1 (+ 3 *C1))
(setArrayElement *A1 *G1 *E1)
(updateArrayLength *G1 *A1)
(:= *H1 (+ 1 *C1))
(getArrayElement *A1 *H1 *I1)
(deref (REF *I1) *B1 (REF *J1))
(:= *K1 (+ *J1 1))
(getArrayElement *B1 *J1 INT)
(getArrayElement *B1 *K1 *L1)
(:= *M1 (x *L1 2))
(createArray *N1 *M1)
(deref (REF *E1) *B1 (REF *O1))
(getArrayElement *B1 *O1 PVAR)
(:= *P1 (+ *O1 1))
(setArrayElement *B1 *O1 ARRAY)
(setArrayElement *B1 *P1 *N1)
(:= *Q1 (+ 3 *C1))
(getArrayElement *A1 *Q1 *R1)
(deref (REF *R1) *B1 (REF *S1))
(:= *T1 (+ *S1 1))
(getArrayElement *B1 *T1 *U1)
(setArrayElement *U1 0 INT)
(setArrayElement *U1 1 2)
(getArrayElement *B1 0 *V1)
(:= *W1 (+ *V1 1))
(:= *X1 (+ *V1 2))
(setArrayElement *B1 0 *X1)
(setArrayElement *B1 *W1 INT)
(:= *Y1 (+ *W1 1))
(setArrayElement *B1 *Y1 3)
(getArrayElement *A1 0 *A2)
(:= *B2 (+ (+ *A2 1) 1))
(setArrayElement *A1 *B2 *W1)
(:= *C2 (+ 3 *C1))
(getArrayElement *A1 *C2 *D2)
(getArrayElement *A1 0 *E2)
(:= *F2 (+ (+ *E2 1) 2))
(setArrayElement *A1 *F2 *D2)
(getArrayElement *B1 0 *G2)
(:= *H2 (+ *G2 1))
(:= *I2 (+ *G2 2))
(setArrayElement *B1 0 *I2)
(setArrayElement *B1 *H2 INT)
(:= *J2 (+ *H2 1))
(setArrayElement *B1 *J2 0)
(getArrayElement *A1 0 *K2)
(:= *L2 (+ (+ *K2 1) 3))
(setArrayElement *A1 *L2 *H2)
(getArrayElement *B1 0 *M2)
(:= *N2 (+ *M2 1))
(:= *O2 (+ *M2 2))
(setArrayElement *B1 0 *O2)
(setArrayElement *B1 *N2 INT)
(:= *P2 (+ *N2 1))
(setArrayElement *B1 *P2 1)
(getArrayElement *A1 0 *Q2)
(:= *R2 (+ (+ *Q2 1) 4))
(setArrayElement *A1 *R2 *N2)
(:= *S2 (+ 1 *C1))
(getArrayElement *A1 *S2 *T2)
(getArrayElement *A1 0 *U2)
(:= *V2 (+ (+ *U2 1) 5))
(setArrayElement *A1 *V2 *T2)
(getArrayElement *A1 0 *W2)
(getArrayElement *A1 1 *X2)
(:= *Y2 (+ *W2 1))
(setArrayElement *A1 *Y2 *X2)
(:= *A3 (+ *Y2 5))
(setArrayElement *A1 0 *A3)
(setArrayElement *A1 1 *Y2)
(call (primeArray5 *A1 *B1))
(:= *B3 (+ 1 *C1))
(getArrayElement *A1 *B3 *C3)
(deref (REF *C3) *B1 (REF *D3))
(:= *E3 (+ *D3 1))
(getArrayElement *B1 *D3 INT)
(getArrayElement *B1 *E3 *F3)
(:= *G3 (- *F3 1))
(:= *H3 (+ 3 *C1))
(getArrayElement *A1 *H3 *I3)
(deref (REF *I3) *B1 (REF *J3))
(:= *K3 (+ *J3 1))
(getArrayElement *B1 *K3 *L3)
(:= *M3 (x *G3 2))
(getArrayElement *L3 *M3 *N3)
(:= *O3 (+ *M3 1))
(getArrayElement *L3 *O3 *P3)
(:= *Q3 (+ 2 *C1))
(getArrayElement *A1 *Q3 *R3)
(deref (REF *R3) *B1 (REF *S3))
(getArrayElement *B1 *S3 PVAR)
(:= *T3 (+ *S3 1))
(setArrayElement *B1 *S3 *N3)
(setArrayElement *B1 *T3 *P3)
(getArrayElement *A1 *C1 *U3)
(setArrayElement *A1 1 *U3)
(:= *V3 (- *C1 1))
(setArrayElement *A1 0 *V3))

(as (primeArray5 *W3 *X3)
(getArrayElement *W3 1 *Y3) :
(getArrayElement *X3 0 *A4)
(:= *B4 (+ *A4 1))
(:= *C4 (+ *A4 2))
(setArrayElement *X3 0 *C4)
(setArrayElement *X3 *B4 PVAR)
(:= *D4 (+ 6 *Y3))
(setArrayElement *W3 *D4 *B4)
(updateArrayLength *D4 *W3)
(primeArray51 *W3 *X3))

(as (primeArray51 *E4 *F4)
(getArrayElement *E4 1 *G4)
(not (== 4 5 *G4 *E4 *F4)) :
(primeArray52 *E4 *F4))

(as (primeArray51 *H4 *I4)
(getArrayElement *H4 1 *J4) :
(getArrayElement *H4 *J4 *K4)
(setArrayElement *H4 1 *K4)
(:= *L4 (- *J4 1))
(setArrayElement *H4 0 *L4))

(as (primeArray52 *M4 *N4)
(getArrayElement *M4 1 *O4)
(getArrayElement *N4 0 *P4)
(:= *Q4 (+ *P4 1))
(:= *R4 (+ *P4 2))
(setArrayElement *N4 0 *R4)
(setArrayElement *N4 *Q4 PVAR)
(:= *S4 (+ 6 *O4))
(setArrayElement *M4 *S4 *Q4)
(updateArrayLength *S4 *M4)
(:= *T4 (+ 2 *O4))
(getArrayElement *M4 *T4 *U4)
(deref (REF *U4) *N4 (REF *V4))
(:= *W4 (+ *V4 1))
(getArrayElement *N4 *W4 *X4)
(:= *Y4 (+ 3 *O4))
(getArrayElement *M4 *Y4 *A5)
(deref (REF *A5) *N4 (REF *B5))
(:= *C5 (+ *B5 1))
(getArrayElement *N4 *B5 INT)
(getArrayElement *N4 *C5 *D5)
(:= *E5 (x *D5 2))
(getArrayElement *X4 *E5 *F5)
(:= *G5 (+ *E5 1))
(getArrayElement *X4 *G5 *H5)
(deref (REF *Q4) *N4 (REF *I5))
(getArrayElement *N4 *I5 PVAR)
(:= *J5 (+ *I5 1))
(setArrayElement *N4 *I5 *F5)
(setArrayElement *N4 *J5 *H5)
(:= *K5 (+ 6 *O4))
(getArrayElement *M4 *K5 *L5)
(deref (REF *L5) *N4 (REF *M5))
(:= *N5 (+ *M5 1))
(getArrayElement *N4 *M5 INT)
(getArrayElement *N4 *N5 *O5)
(:= *P5 (+ 6 *O4))
(getArrayElement *M4 *P5 *Q5)
(deref (REF *Q5) *N4 (REF *R5))
(:= *S5 (+ *R5 1))
(getArrayElement *N4 *R5 INT)
(getArrayElement *N4 *S5 *T5)
(:= *U5 (x *O5 *T5))
(not (< 1 (INT *U5) *O4 *M4 *N4)) :
(primeArray53 *M4 *N4))

(as (primeArray52 *V5 *W5)
(getArrayElement *V5 1 *X5) :
(:= *Y5 (+ 2 *X5))
(getArrayElement *V5 *Y5 *A6)
(deref (REF *A6) *W5 (REF *B6))
(:= *C6 (+ *B6 1))
(getArrayElement *W5 *C6 *D6)
(:= *E6 (+ 4 *X5))
(getArrayElement *V5 *E6 *F6)
(deref (REF *F6) *W5 (REF *G6))
(:= *H6 (+ *G6 1))
(getArrayElement *W5 *G6 INT)
(getArrayElement *W5 *H6 *I6)
(:= *J6 (+ 1 *X5))
(getArrayElement *V5 *J6 *K6)
(deref (REF *K6) *W5 (REF *L6))
(:= *M6 (+ *L6 1))
(getArrayElement *W5 *L6 *N6)
(getArrayElement *W5 *M6 *O6)
(:= *P6 (x *I6 2))
(setArrayElement *D6 *P6 *N6)
(:= *Q6 (+ *P6 1))
(setArrayElement *D6 *Q6 *O6)
(:= *R6 (+ 4 *X5))
(getArrayElement *V5 *R6 *S6)
(deref (REF *S6) *W5 (REF *T6))
(:= *U6 (+ *T6 1))
(getArrayElement *W5 *T6 INT)
(getArrayElement *W5 *U6 *V6)
(:= *W6 (+ *V6 1))
(:= *X6 (+ 4 *X5))
(getArrayElement *V5 *X6 *Y6)
(:= *A7 (+ *Y6 1))
(setArrayElement *W5 *Y6 INT)
(setArrayElement *W5 *A7 *W6)
(:= *B7 (+ 3 *X5))
(getArrayElement *V5 *B7 *C7)
(:= *D7 (+ *C7 1))
(setArrayElement *W5 *C7 INT)
(setArrayElement *W5 *D7 1)
(:= *E7 (+ 1 *X5))
(getArrayElement *V5 *E7 *F7)
(deref (REF *F7) *W5 (REF *G7))
(:= *H7 (+ *G7 1))
(getArrayElement *W5 *G7 INT)
(getArrayElement *W5 *H7 *I7)
(:= *J7 (+ *I7 2))
(:= *K7 (+ 1 *X5))
(getArrayElement *V5 *K7 *L7)
(:= *M7 (+ *L7 1))
(setArrayElement *W5 *L7 INT)
(setArrayElement *W5 *M7 *J7)
(primeArray51 *V5 *W5))

(as (primeArray53 *N7 *O7)
(getArrayElement *N7 1 *P7)
(getArrayElement *O7 0 *Q7)
(:= *R7 (+ *Q7 1))
(:= *S7 (+ *Q7 2))
(setArrayElement *O7 0 *S7)
(setArrayElement *O7 *R7 PVAR)
(:= *T7 (+ 6 *P7))
(setArrayElement *N7 *T7 *R7)
(updateArrayLength *T7 *N7)
(:= *U7 (+ 2 *P7))
(getArrayElement *N7 *U7 *V7)
(deref (REF *V7) *O7 (REF *W7))
(:= *X7 (+ *W7 1))
(getArrayElement *O7 *X7 *Y7)
(:= *A8 (+ 3 *P7))
(getArrayElement *N7 *A8 *B8)
(deref (REF *B8) *O7 (REF *C8))
(:= *D8 (+ *C8 1))
(getArrayElement *O7 *C8 INT)
(getArrayElement *O7 *D8 *E8)
(:= *F8 (x *E8 2))
(getArrayElement *Y7 *F8 *G8)
(:= *H8 (+ *F8 1))
(getArrayElement *Y7 *H8 *I8)
(deref (REF *R7) *O7 (REF *J8))
(getArrayElement *O7 *J8 PVAR)
(:= *K8 (+ *J8 1))
(setArrayElement *O7 *J8 *G8)
(setArrayElement *O7 *K8 *I8)
(:= *L8 (+ 1 *P7))
(getArrayElement *N7 *L8 *M8)
(deref (REF *M8) *O7 (REF *N8))
(:= *O8 (+ *N8 1))
(getArrayElement *O7 *N8 INT)
(getArrayElement *O7 *O8 *P8)
(:= *Q8 (+ 6 *P7))
(getArrayElement *N7 *Q8 *R8)
(deref (REF *R8) *O7 (REF *S8))
(:= *T8 (+ *S8 1))
(getArrayElement *O7 *S8 INT)
(getArrayElement *O7 *T8 *U8)
(:= *V8 (mod *P8 *U8))
(not (== (INT 0) (INT *V8) *P7 *N7 *O7)) :
(primeArray54 *N7 *O7))

(as (primeArray53 *W8 *X8)
(getArrayElement *W8 1 *Y8) :
(:= *A9 (+ 3 *Y8))
(getArrayElement *W8 *A9 *B9)
(:= *C9 (+ *B9 1))
(setArrayElement *X8 *B9 INT)
(setArrayElement *X8 *C9 1)
(:= *D9 (+ 1 *Y8))
(getArrayElement *W8 *D9 *E9)
(deref (REF *E9) *X8 (REF *F9))
(:= *G9 (+ *F9 1))
(getArrayElement *X8 *F9 INT)
(getArrayElement *X8 *G9 *H9)
(:= *I9 (+ *H9 2))
(:= *J9 (+ 1 *Y8))
(getArrayElement *W8 *J9 *K9)
(:= *L9 (+ *K9 1))
(setArrayElement *X8 *K9 INT)
(setArrayElement *X8 *L9 *I9)
(primeArray51 *W8 *X8))

(as (primeArray54 *M9 *N9)
(getArrayElement *M9 1 *O9) :
(:= *P9 (+ 3 *O9))
(getArrayElement *M9 *P9 *Q9)
(deref (REF *Q9) *N9 (REF *R9))
(:= *S9 (+ *R9 1))
(getArrayElement *N9 *R9 INT)
(getArrayElement *N9 *S9 *T9)
(:= *U9 (+ *T9 1))
(:= *V9 (+ 3 *O9))
(getArrayElement *M9 *V9 *W9)
(:= *X9 (+ *W9 1))
(setArrayElement *N9 *W9 INT)
(setArrayElement *N9 *X9 *U9)
(primeArray51 *M9 *N9))

----------------------------------------------------------
succeeded.
(peval "nthprime.eti")

こんな感じに,runtime.eti から include したルールの unfold とか定数畳み込み (算術単一化,記号処理) とか融合変換 (ヘッド部に影響を与えない単一化とかをやれるだけやって,余計な処理や中間構造を取り除く) を,再帰的にやれるだけやり,後には非常にプリミティブなルールと,ETI に組み込みの B ルールだけが残ります.

C コードジェネレーションには不要なので取り除かれてますが, ?-(include "runtime.eti"). すれば,ちゃんと一番最初のと同じ動作をすることが確認できます.というか,ETI の上での評価をあらかじめ部分的に安全なところだけをやっているだけなので,当たり前ですが.

not の評価とか,いろいろ微妙なところはまだやってないで,かなり甘い部分評価です.基本的な型判定ルールとかだけだったら,問題は無いので,そのうちに.それでも,あらかじめ展開しておくと,2 倍程度には容易に高速化されます.全てが等価変換ルールで定義されているので,こういうプログラムの合成が容易なのですねぇ.

本当は,型推論とか,もっといろいろ最適化や検証は可能なんですけど,とりあえず今は部分評価だけ.まぁ,やることはいくらでもあります… orz

あとは,これを,とりあえず大域的な最適化とか何も考えないで, 1-to-1 で C 言語に落とすと,こうなります.この時にも,いろいろ小手先の最適化とか,コードジェネレーションのためのアレコレが.(INT とか,(REF とか,微妙に型が付いているのが確認できると思います.たいしたことは何もしてませんが.単なる生メモリの塊 (ワード配列) なのに,ヒープとかラベルが付いてますが,まぁあまり細かいところは気にしないでください…

#include "et.h"

bool nthprime2(word stack[], word heap[]) {
word base;

{
// (getArrayElement stack 1 *A)
base = stack[1];
// (getArrayElement heap 0 *B) = heap[0]
int C = heap[0] + 1;
// (:= *C (+ (INT "heap[0]") 1))
int D = heap[0] + 2;
// (:= *D (+ (INT "heap[0]") 2))
// (setArrayElement heap 0 (INT "D"))
heap[0] = D;
// (setArrayElement heap (INT "C") PVAR)
heap[C] = PVAR;
int E = 3 + base;
// (:= *E (+ 3 base))
// (setArrayElement stack (INT "E") (INT "C"))
stack[E] = C;
// (updateArrayLength (INT "E") stack)

if(stack[0] < E)
stack[0] = E;

// (nthprime21 stack heap)

goto nthprime21;
}

nthprime21 :
{

// (getArrayElement stack 1 *F)
base = stack[1];
// (not (== (1 (INT 1) base stack heap)))
if(1 == ideref(1, base, stack, heap))
goto nthprime211;

// (nthprime22 stack heap)

goto nthprime22;
}

nthprime211 :
{

// (getArrayElement stack 1 *G)
base = stack[1];
int H = 2 + base;
// (:= *H (+ 2 base))
// (getArrayElement stack (INT "H") *I) = stack[H]
// (setArrayElement heap (INT "stack[H]") INT)
heap[stack[H]] = INT;
int J = stack[H] + 1;
// (:= *J (+ (INT "stack[H]") 1))
// (setArrayElement heap (INT "J") 2)
heap[J] = 2;
// (getArrayElement stack base *K) = stack[base]
// (setArrayElement stack 1 (INT "stack[base]"))
stack[1] = stack[base];
int L = base - 1;
// (:= *L (- base 1))
// (setArrayElement stack 0 (INT "L"))
stack[0] = L;
return (bool)stack[base];
}
nthprime22 :
{

// (getArrayElement stack 1 *M)
base = stack[1];
// (getArrayElement heap 0 *N) = heap[0]
int O = heap[0] + 1;
// (:= *O (+ (INT "heap[0]") 1))
int P = heap[0] + 2;
// (:= *P (+ (INT "heap[0]") 2))
// (setArrayElement heap 0 (INT "P"))
heap[0] = P;
// (setArrayElement heap (INT "O") PVAR)
heap[O] = PVAR;
int Q = 3 + base;
// (:= *Q (+ 3 base))
// (setArrayElement stack (INT "Q") (INT "O"))
stack[Q] = O;
// (updateArrayLength (INT "Q") stack)

if(stack[0] < Q)
stack[0] = Q;

int R = 1 + base;
// (:= *R (+ 1 base))
// (getArrayElement stack (INT "R") *S) = stack[R]
word T = stack[R];
while(heap[T] == REF)
T = heap[T + 1];

int U = T + 1;
// (:= *U (+ (REF "T") 1))
// (getArrayElement heap (REF "T") INT)
if(heap[T] != INT)
printf("werning : heap[T] != INT\n\n");
// (getArrayElement heap (INT "U") *V) = heap[U]
int W = heap[U] * 2;
// (:= *W (x (INT "heap[U]") 2))
// (createArray *X (INT "W"))
word X = heap[0] + 1;
heap[0] = W + 2;
heap[X] = ARRAY;
heap[X + 1] = W;

word Y = O;
while(heap[Y] == REF)
Y = heap[Y + 1];

// (getArrayElement heap (REF "Y") PVAR)
if(heap[Y] != PVAR)
printf("werning : heap[Y] != PVAR\n\n");
int A1 = Y + 1;
// (:= *A1 (+ (REF "Y") 1))
// (setArrayElement heap (REF "Y") ARRAY)
heap[Y] = ARRAY;
// (setArrayElement heap (INT "A1") (REF "X"))
heap[A1] = X;
int B1 = 3 + base;
// (:= *B1 (+ 3 base))
// (getArrayElement stack (INT "B1") *C1) = stack[B1]
word D1 = stack[B1];
while(heap[D1] == REF)
D1 = heap[D1 + 1];

int E1 = D1 + 1;
// (:= *E1 (+ (REF "D1") 1))
// (getArrayElement heap (INT "E1") *F1) = heap[E1]
// (setArrayElement (INT "heap[E1]") 0 INT)
heap[heap[E1] + 0 + 2] = INT;
// (setArrayElement (INT "heap[E1]") 1 2)
heap[heap[E1] + 1 + 2] = 2;
// (getArrayElement heap 0 *G1) = heap[0]
int H1 = heap[0] + 1;
// (:= *H1 (+ (INT "heap[0]") 1))
int I1 = heap[0] + 2;
// (:= *I1 (+ (INT "heap[0]") 2))
// (setArrayElement heap 0 (INT "I1"))
heap[0] = I1;
// (setArrayElement heap (INT "H1") INT)
heap[H1] = INT;
int J1 = H1 + 1;
// (:= *J1 (+ (INT "H1") 1))
// (setArrayElement heap (INT "J1") 3)
heap[J1] = 3;
// (getArrayElement stack 0 *K1) = stack[0]
int L1 = stack[0] + 1 + 1;
// (:= *L1 (+ (+ (INT "stack[0]") 1) 1))
// (setArrayElement stack (INT "L1") (INT "H1"))
stack[L1] = H1;
int M1 = 3 + base;
// (:= *M1 (+ 3 base))
// (getArrayElement stack (INT "M1") *N1) = stack[M1]
// (getArrayElement stack 0 *O1) = stack[0]
int P1 = stack[0] + 1 + 2;
// (:= *P1 (+ (+ (INT "stack[0]") 1) 2))
// (setArrayElement stack (INT "P1") (INT "stack[M1]"))
stack[P1] = stack[M1];
// (getArrayElement heap 0 *Q1) = heap[0]
int R1 = heap[0] + 1;
// (:= *R1 (+ (INT "heap[0]") 1))
int S1 = heap[0] + 2;
// (:= *S1 (+ (INT "heap[0]") 2))
// (setArrayElement heap 0 (INT "S1"))
heap[0] = S1;
// (setArrayElement heap (INT "R1") INT)
heap[R1] = INT;
int T1 = R1 + 1;
// (:= *T1 (+ (INT "R1") 1))
// (setArrayElement heap (INT "T1") 0)
heap[T1] = 0;
// (getArrayElement stack 0 *U1) = stack[0]
int V1 = stack[0] + 1 + 3;
// (:= *V1 (+ (+ (INT "stack[0]") 1) 3))
// (setArrayElement stack (INT "V1") (INT "R1"))
stack[V1] = R1;
// (getArrayElement heap 0 *W1) = heap[0]
int X1 = heap[0] + 1;
// (:= *X1 (+ (INT "heap[0]") 1))
int Y1 = heap[0] + 2;
// (:= *Y1 (+ (INT "heap[0]") 2))
// (setArrayElement heap 0 (INT "Y1"))
heap[0] = Y1;
// (setArrayElement heap (INT "X1") INT)
heap[X1] = INT;
int A2 = X1 + 1;
// (:= *A2 (+ (INT "X1") 1))
// (setArrayElement heap (INT "A2") 1)
heap[A2] = 1;
// (getArrayElement stack 0 *B2) = stack[0]
int C2 = stack[0] + 1 + 4;
// (:= *C2 (+ (+ (INT "stack[0]") 1) 4))
// (setArrayElement stack (INT "C2") (INT "X1"))
stack[C2] = X1;
int D2 = 1 + base;
// (:= *D2 (+ 1 base))
// (getArrayElement stack (INT "D2") *E2) = stack[D2]
// (getArrayElement stack 0 *F2) = stack[0]
int G2 = stack[0] + 1 + 5;
// (:= *G2 (+ (+ (INT "stack[0]") 1) 5))
// (setArrayElement stack (INT "G2") (INT "stack[D2]"))
stack[G2] = stack[D2];
// (getArrayElement stack 0 *H2) = stack[0]
// (getArrayElement stack 1 *I2)
base = stack[1];
int J2 = stack[0] + 1;
// (:= *J2 (+ (INT "stack[0]") 1))
// (setArrayElement stack (INT "J2") base)
stack[J2] = base;
int K2 = J2 + 5;
// (:= *K2 (+ (INT "J2") 5))
// (setArrayElement stack 0 (INT "K2"))
stack[0] = K2;
// (setArrayElement stack 1 (INT "J2"))
stack[1] = J2;
// (call (primeArray5 stack heap))
goto primeArray5;
int M2 = 1 + base;
// (:= *M2 (+ 1 base))
// (getArrayElement stack (INT "M2") *N2) = stack[M2]
word O2 = stack[M2];
while(heap[O2] == REF)
O2 = heap[O2 + 1];

int P2 = O2 + 1;
// (:= *P2 (+ (REF "O2") 1))
// (getArrayElement heap (REF "O2") INT)
if(heap[O2] != INT)
printf("werning : heap[O2] != INT\n\n");
// (getArrayElement heap (INT "P2") *Q2) = heap[P2]
int R2 = heap[P2] - 1;
// (:= *R2 (- (INT "heap[P2]") 1))
int S2 = 3 + base;
// (:= *S2 (+ 3 base))
// (getArrayElement stack (INT "S2") *T2) = stack[S2]
word U2 = stack[S2];
while(heap[U2] == REF)
U2 = heap[U2 + 1];

int V2 = U2 + 1;
// (:= *V2 (+ (REF "U2") 1))
// (getArrayElement heap (INT "V2") *W2) = heap[V2]
int X2 = R2 * 2;
// (:= *X2 (x (INT "R2") 2))
// (getArrayElement (INT "heap[V2]") (INT "X2") *Y2) = heap[heap[V2] + X2]
int A3 = X2 + 1;
// (:= *A3 (+ (INT "X2") 1))
// (getArrayElement (INT "heap[V2]") (INT "A3") *B3) = heap[heap[V2] + A3]
int C3 = 2 + base;
// (:= *C3 (+ 2 base))
// (getArrayElement stack (INT "C3") *D3) = stack[C3]
word E3 = stack[C3];
while(heap[E3] == REF)
E3 = heap[E3 + 1];

// (getArrayElement heap (REF "E3") PVAR)
if(heap[E3] != PVAR)
printf("werning : heap[E3] != PVAR\n\n");
int F3 = E3 + 1;
// (:= *F3 (+ (REF "E3") 1))
// (setArrayElement heap (REF "E3") (INT "heap[heap[V2] + X2]"))
heap[E3] = heap[heap[V2] + X2];
// (setArrayElement heap (INT "F3") (INT "heap[heap[V2] + A3]"))
heap[F3] = heap[heap[V2] + A3];
// (getArrayElement stack base *G3) = stack[base]
// (setArrayElement stack 1 (INT "stack[base]"))
stack[1] = stack[base];
int H3 = base - 1;
// (:= *H3 (- base 1))
// (setArrayElement stack 0 (INT "H3"))
stack[0] = H3;
return (bool)stack[base];
}
primeArray5 :
{

// (getArrayElement stack 1 *I3)
base = stack[1];
// (getArrayElement heap 0 *J3) = heap[0]
int K3 = heap[0] + 1;
// (:= *K3 (+ (INT "heap[0]") 1))
int L3 = heap[0] + 2;
// (:= *L3 (+ (INT "heap[0]") 2))
// (setArrayElement heap 0 (INT "L3"))
heap[0] = L3;
// (setArrayElement heap (INT "K3") PVAR)
heap[K3] = PVAR;
int M3 = 6 + base;
// (:= *M3 (+ 6 base))
// (setArrayElement stack (INT "M3") (INT "K3"))
stack[M3] = K3;
// (updateArrayLength (INT "M3") stack)

if(stack[0] < M3)
stack[0] = M3;

// (primeArray51 stack heap)

goto primeArray51;
}

primeArray51 :
{

// (getArrayElement stack 1 *N3)
base = stack[1];
// (not (== 4 5 base stack heap))
if(ideref(4, base, stack, heap) == ideref(5, base, stack, heap))
goto primeArray511;

// (primeArray52 stack heap)

goto primeArray52;
}

primeArray511 :
{

// (getArrayElement stack 1 *O3)
base = stack[1];
// (getArrayElement stack base *P3) = stack[base]
// (setArrayElement stack 1 (INT "stack[base]"))
stack[1] = stack[base];
int Q3 = base - 1;
// (:= *Q3 (- base 1))
// (setArrayElement stack 0 (INT "Q3"))
stack[0] = Q3;
return (bool)stack[base];
}
primeArray52 :
{

// (getArrayElement stack 1 *R3)
base = stack[1];
// (getArrayElement heap 0 *S3) = heap[0]
int T3 = heap[0] + 1;
// (:= *T3 (+ (INT "heap[0]") 1))
int U3 = heap[0] + 2;
// (:= *U3 (+ (INT "heap[0]") 2))
// (setArrayElement heap 0 (INT "U3"))
heap[0] = U3;
// (setArrayElement heap (INT "T3") PVAR)
heap[T3] = PVAR;
int V3 = 6 + base;
// (:= *V3 (+ 6 base))
// (setArrayElement stack (INT "V3") (INT "T3"))
stack[V3] = T3;
// (updateArrayLength (INT "V3") stack)

if(stack[0] < V3)
stack[0] = V3;

int W3 = 2 + base;
// (:= *W3 (+ 2 base))
// (getArrayElement stack (INT "W3") *X3) = stack[W3]
word Y3 = stack[W3];
while(heap[Y3] == REF)
Y3 = heap[Y3 + 1];

int A4 = Y3 + 1;
// (:= *A4 (+ (REF "Y3") 1))
// (getArrayElement heap (INT "A4") *B4) = heap[A4]
int C4 = 3 + base;
// (:= *C4 (+ 3 base))
// (getArrayElement stack (INT "C4") *D4) = stack[C4]
word E4 = stack[C4];
while(heap[E4] == REF)
E4 = heap[E4 + 1];

int F4 = E4 + 1;
// (:= *F4 (+ (REF "E4") 1))
// (getArrayElement heap (REF "E4") INT)
if(heap[E4] != INT)
printf("werning : heap[E4] != INT\n\n");
// (getArrayElement heap (INT "F4") *G4) = heap[F4]
int H4 = heap[F4] * 2;
// (:= *H4 (x (INT "heap[F4]") 2))
// (getArrayElement (INT "heap[A4]") (INT "H4") *I4) = heap[heap[A4] + H4]
int J4 = H4 + 1;
// (:= *J4 (+ (INT "H4") 1))
// (getArrayElement (INT "heap[A4]") (INT "J4") *K4) = heap[heap[A4] + J4]
word L4 = T3;
while(heap[L4] == REF)
L4 = heap[L4 + 1];

// (getArrayElement heap (REF "L4") PVAR)
if(heap[L4] != PVAR)
printf("werning : heap[L4] != PVAR\n\n");
int M4 = L4 + 1;
// (:= *M4 (+ (REF "L4") 1))
// (setArrayElement heap (REF "L4") (INT "heap[heap[A4] + H4]"))
heap[L4] = heap[heap[A4] + H4];
// (setArrayElement heap (INT "M4") (INT "heap[heap[A4] + J4]"))
heap[M4] = heap[heap[A4] + J4];
int N4 = 6 + base;
// (:= *N4 (+ 6 base))
// (getArrayElement stack (INT "N4") *O4) = stack[N4]
word P4 = stack[N4];
while(heap[P4] == REF)
P4 = heap[P4 + 1];

int Q4 = P4 + 1;
// (:= *Q4 (+ (REF "P4") 1))
// (getArrayElement heap (REF "P4") INT)
if(heap[P4] != INT)
printf("werning : heap[P4] != INT\n\n");
// (getArrayElement heap (INT "Q4") *R4) = heap[Q4]
int S4 = 6 + base;
// (:= *S4 (+ 6 base))
// (getArrayElement stack (INT "S4") *T4) = stack[S4]
word U4 = stack[S4];
while(heap[U4] == REF)
U4 = heap[U4 + 1];

int V4 = U4 + 1;
// (:= *V4 (+ (REF "U4") 1))
// (getArrayElement heap (REF "U4") INT)
if(heap[U4] != INT)
printf("werning : heap[U4] != INT\n\n");
// (getArrayElement heap (INT "V4") *W4) = heap[V4]
int X4 = heap[Q4] * heap[V4];
// (:= *X4 (x (INT "heap[Q4]") (INT "heap[V4]")))
// (not (< (1 (INT (INT "X4")) base stack heap)))
if(1 < ideref(X4, base, stack, heap))
goto primeArray521;

// (primeArray53 stack heap)

goto primeArray53;
}

primeArray521 :
{

// (getArrayElement stack 1 *Y4)
base = stack[1];
int A5 = 2 + base;
// (:= *A5 (+ 2 base))
// (getArrayElement stack (INT "A5") *B5) = stack[A5]
word C5 = stack[A5];
while(heap[C5] == REF)
C5 = heap[C5 + 1];

int D5 = C5 + 1;
// (:= *D5 (+ (REF "C5") 1))
// (getArrayElement heap (INT "D5") *E5) = heap[D5]
int F5 = 4 + base;
// (:= *F5 (+ 4 base))
// (getArrayElement stack (INT "F5") *G5) = stack[F5]
word H5 = stack[F5];
while(heap[H5] == REF)
H5 = heap[H5 + 1];

int I5 = H5 + 1;
// (:= *I5 (+ (REF "H5") 1))
// (getArrayElement heap (REF "H5") INT)
if(heap[H5] != INT)
printf("werning : heap[H5] != INT\n\n");
// (getArrayElement heap (INT "I5") *J5) = heap[I5]
int K5 = 1 + base;
// (:= *K5 (+ 1 base))
// (getArrayElement stack (INT "K5") *L5) = stack[K5]
word M5 = stack[K5];
while(heap[M5] == REF)
M5 = heap[M5 + 1];

int N5 = M5 + 1;
// (:= *N5 (+ (REF "M5") 1))
// (getArrayElement heap (REF "M5") *O5) = heap[M5]
// (getArrayElement heap (INT "N5") *P5) = heap[N5]
int Q5 = heap[I5] * 2;
// (:= *Q5 (x (INT "heap[I5]") 2))
// (setArrayElement (INT "heap[D5]") (INT "Q5") (INT "heap[M5]"))
heap[heap[D5] + Q5 + 2] = heap[M5];
int R5 = Q5 + 1;
// (:= *R5 (+ (INT "Q5") 1))
// (setArrayElement (INT "heap[D5]") (INT "R5") (INT "heap[N5]"))
heap[heap[D5] + R5 + 2] = heap[N5];
int S5 = 4 + base;
// (:= *S5 (+ 4 base))
// (getArrayElement stack (INT "S5") *T5) = stack[S5]
word U5 = stack[S5];
while(heap[U5] == REF)
U5 = heap[U5 + 1];

int V5 = U5 + 1;
// (:= *V5 (+ (REF "U5") 1))
// (getArrayElement heap (REF "U5") INT)
if(heap[U5] != INT)
printf("werning : heap[U5] != INT\n\n");
// (getArrayElement heap (INT "V5") *W5) = heap[V5]
int X5 = heap[V5] + 1;
// (:= *X5 (+ (INT "heap[V5]") 1))
int Y5 = 4 + base;
// (:= *Y5 (+ 4 base))
// (getArrayElement stack (INT "Y5") *A6) = stack[Y5]
int B6 = stack[Y5] + 1;
// (:= *B6 (+ (INT "stack[Y5]") 1))
// (setArrayElement heap (INT "stack[Y5]") INT)
heap[stack[Y5]] = INT;
// (setArrayElement heap (INT "B6") (INT "X5"))
heap[B6] = X5;
int C6 = 3 + base;
// (:= *C6 (+ 3 base))
// (getArrayElement stack (INT "C6") *D6) = stack[C6]
int E6 = stack[C6] + 1;
// (:= *E6 (+ (INT "stack[C6]") 1))
// (setArrayElement heap (INT "stack[C6]") INT)
heap[stack[C6]] = INT;
// (setArrayElement heap (INT "E6") 1)
heap[E6] = 1;
int F6 = 1 + base;
// (:= *F6 (+ 1 base))
// (getArrayElement stack (INT "F6") *G6) = stack[F6]
word H6 = stack[F6];
while(heap[H6] == REF)
H6 = heap[H6 + 1];

int I6 = H6 + 1;
// (:= *I6 (+ (REF "H6") 1))
// (getArrayElement heap (REF "H6") INT)
if(heap[H6] != INT)
printf("werning : heap[H6] != INT\n\n");
// (getArrayElement heap (INT "I6") *J6) = heap[I6]
int K6 = heap[I6] + 2;
// (:= *K6 (+ (INT "heap[I6]") 2))
int L6 = 1 + base;
// (:= *L6 (+ 1 base))
// (getArrayElement stack (INT "L6") *M6) = stack[L6]
int N6 = stack[L6] + 1;
// (:= *N6 (+ (INT "stack[L6]") 1))
// (setArrayElement heap (INT "stack[L6]") INT)
heap[stack[L6]] = INT;
// (setArrayElement heap (INT "N6") (INT "K6"))
heap[N6] = K6;
// (primeArray51 stack heap)

goto primeArray51;
}

primeArray53 :
{

// (getArrayElement stack 1 *O6)
base = stack[1];
// (getArrayElement heap 0 *P6) = heap[0]
int Q6 = heap[0] + 1;
// (:= *Q6 (+ (INT "heap[0]") 1))
int R6 = heap[0] + 2;
// (:= *R6 (+ (INT "heap[0]") 2))
// (setArrayElement heap 0 (INT "R6"))
heap[0] = R6;
// (setArrayElement heap (INT "Q6") PVAR)
heap[Q6] = PVAR;
int S6 = 6 + base;
// (:= *S6 (+ 6 base))
// (setArrayElement stack (INT "S6") (INT "Q6"))
stack[S6] = Q6;
// (updateArrayLength (INT "S6") stack)

if(stack[0] < S6)
stack[0] = S6;

int T6 = 2 + base;
// (:= *T6 (+ 2 base))
// (getArrayElement stack (INT "T6") *U6) = stack[T6]
word V6 = stack[T6];
while(heap[V6] == REF)
V6 = heap[V6 + 1];

int W6 = V6 + 1;
// (:= *W6 (+ (REF "V6") 1))
// (getArrayElement heap (INT "W6") *X6) = heap[W6]
int Y6 = 3 + base;
// (:= *Y6 (+ 3 base))
// (getArrayElement stack (INT "Y6") *A7) = stack[Y6]
word B7 = stack[Y6];
while(heap[B7] == REF)
B7 = heap[B7 + 1];

int C7 = B7 + 1;
// (:= *C7 (+ (REF "B7") 1))
// (getArrayElement heap (REF "B7") INT)
if(heap[B7] != INT)
printf("werning : heap[B7] != INT\n\n");
// (getArrayElement heap (INT "C7") *D7) = heap[C7]
int E7 = heap[C7] * 2;
// (:= *E7 (x (INT "heap[C7]") 2))
// (getArrayElement (INT "heap[W6]") (INT "E7") *F7) = heap[heap[W6] + E7]
int G7 = E7 + 1;
// (:= *G7 (+ (INT "E7") 1))
// (getArrayElement (INT "heap[W6]") (INT "G7") *H7) = heap[heap[W6] + G7]
word I7 = Q6;
while(heap[I7] == REF)
I7 = heap[I7 + 1];

// (getArrayElement heap (REF "I7") PVAR)
if(heap[I7] != PVAR)
printf("werning : heap[I7] != PVAR\n\n");
int J7 = I7 + 1;
// (:= *J7 (+ (REF "I7") 1))
// (setArrayElement heap (REF "I7") (INT "heap[heap[W6] + E7]"))
heap[I7] = heap[heap[W6] + E7];
// (setArrayElement heap (INT "J7") (INT "heap[heap[W6] + G7]"))
heap[J7] = heap[heap[W6] + G7];
int K7 = 1 + base;
// (:= *K7 (+ 1 base))
// (getArrayElement stack (INT "K7") *L7) = stack[K7]
word M7 = stack[K7];
while(heap[M7] == REF)
M7 = heap[M7 + 1];

int N7 = M7 + 1;
// (:= *N7 (+ (REF "M7") 1))
// (getArrayElement heap (REF "M7") INT)
if(heap[M7] != INT)
printf("werning : heap[M7] != INT\n\n");
// (getArrayElement heap (INT "N7") *O7) = heap[N7]
int P7 = 6 + base;
// (:= *P7 (+ 6 base))
// (getArrayElement stack (INT "P7") *Q7) = stack[P7]
word R7 = stack[P7];
while(heap[R7] == REF)
R7 = heap[R7 + 1];

int S7 = R7 + 1;
// (:= *S7 (+ (REF "R7") 1))
// (getArrayElement heap (REF "R7") INT)
if(heap[R7] != INT)
printf("werning : heap[R7] != INT\n\n");
// (getArrayElement heap (INT "S7") *T7) = heap[S7]
int U7 = heap[N7] % heap[S7];
// (:= *U7 (mod (INT "heap[N7]") (INT "heap[S7]")))
// (not (== (INT 0) (INT (INT "U7")) base stack heap))
if(0 == U7)
goto primeArray531;

// (primeArray54 stack heap)

goto primeArray54;
}

primeArray531 :
{

// (getArrayElement stack 1 *V7)
base = stack[1];
int W7 = 3 + base;
// (:= *W7 (+ 3 base))
// (getArrayElement stack (INT "W7") *X7) = stack[W7]
int Y7 = stack[W7] + 1;
// (:= *Y7 (+ (INT "stack[W7]") 1))
// (setArrayElement heap (INT "stack[W7]") INT)
heap[stack[W7]] = INT;
// (setArrayElement heap (INT "Y7") 1)
heap[Y7] = 1;
int A8 = 1 + base;
// (:= *A8 (+ 1 base))
// (getArrayElement stack (INT "A8") *B8) = stack[A8]
word C8 = stack[A8];
while(heap[C8] == REF)
C8 = heap[C8 + 1];

int D8 = C8 + 1;
// (:= *D8 (+ (REF "C8") 1))
// (getArrayElement heap (REF "C8") INT)
if(heap[C8] != INT)
printf("werning : heap[C8] != INT\n\n");
// (getArrayElement heap (INT "D8") *E8) = heap[D8]
int F8 = heap[D8] + 2;
// (:= *F8 (+ (INT "heap[D8]") 2))
int G8 = 1 + base;
// (:= *G8 (+ 1 base))
// (getArrayElement stack (INT "G8") *H8) = stack[G8]
int I8 = stack[G8] + 1;
// (:= *I8 (+ (INT "stack[G8]") 1))
// (setArrayElement heap (INT "stack[G8]") INT)
heap[stack[G8]] = INT;
// (setArrayElement heap (INT "I8") (INT "F8"))
heap[I8] = F8;
// (primeArray51 stack heap)

goto primeArray51;
}

primeArray54 :
{

// (getArrayElement stack 1 *J8)
base = stack[1];
int K8 = 3 + base;
// (:= *K8 (+ 3 base))
// (getArrayElement stack (INT "K8") *L8) = stack[K8]
word M8 = stack[K8];
while(heap[M8] == REF)
M8 = heap[M8 + 1];

int N8 = M8 + 1;
// (:= *N8 (+ (REF "M8") 1))
// (getArrayElement heap (REF "M8") INT)
if(heap[M8] != INT)
printf("werning : heap[M8] != INT\n\n");
// (getArrayElement heap (INT "N8") *O8) = heap[N8]
int P8 = heap[N8] + 1;
// (:= *P8 (+ (INT "heap[N8]") 1))
int Q8 = 3 + base;
// (:= *Q8 (+ 3 base))
// (getArrayElement stack (INT "Q8") *R8) = stack[Q8]
int S8 = stack[Q8] + 1;
// (:= *S8 (+ (INT "stack[Q8]") 1))
// (setArrayElement heap (INT "stack[Q8]") INT)
heap[stack[Q8]] = INT;
// (setArrayElement heap (INT "S8") (INT "P8"))
heap[S8] = P8;
// (primeArray51 stack heap)

goto primeArray51;
}

}

こんな感じで,ひとつのファイル内のルール集合は,巨大な一つの C 関数にコンパイルされます.
見た目は C ですけど,やってることはアセンブラです.
関数コールとかも,自前でスタック管理して,スタックフレーム積んで (単なる,メモリを表現した配列へのインデックスとかだけですが.2 本のワードの配列だけで全てのデータ構造の表現と処理を行ってます) スタックポインタずらして goto とかになってます.ET において,変数のスコープはルール内のみなので,テキトーにスコープが {} で切ってあって,他のルールへは goto で全部移動してます.
普通は,関数を超えた goto とかはできないのですが,全部一個の関数に無理やりしているので,何でもアリアリ赤 5 個入り,アリス焼き鳥チップ有り,一枚千円役満御祝儀 13 枚です.
これにより,あんまりポインタも使ってませんし,解析も容易に成りそうなので,C コンパイラがいろいろがんばってくれそう,という期待も膨らみますが,とりあえず本当にテキトーに作ったものなので,やたら変数が宣言されていたりと,それ以上に今のところは無駄だらけ.追々何とかしていかないと.

とりあえず,メタ計算で,変数が使われる回数ぐらいは調べて,無駄な中間変数を潰したりしないと駄目かも.C コンパイラに期待しても良いのですが,生成されたコードを読むのも大変過ぎますし.

というか,まだちゃんと動いてないので,これからもうちょっといろいろ作りこんで,デバッグ環境も整えていかないと.

さすがに,この規模になってくると,コンパイラのデバッグも一苦労.まぁ,たぶんいくつか等価変換のパターンの記述漏れがあるということで,おおよその見当は付いてますが.たぶん,配列周り (というか,ここしか無い).一見ダラダラと長くて複雑そうに見えますけど,構造的にはかなり単純なので.

ネイティブコンパイラを作ってる人達もこんな感じでいろいろ苦労しているのだろうか ? 生成されたアセンブリ言語とにらめっこよりは,まだマシなんだろうけど… 疲れる.

まぁ,コンパイラみたいな,コードの等価変換ルールを延々と書き並べていくような処理は,ET のお家芸なので,コンパイラのコード自体は 1000 行程度のがいくつかと,かなり短いんだけど.C へのトランスレータなんて,200 〜 300 行ぐらいだし.D ルールのレベルで全ての C の概念 (コンパイラが使う程度のサブセットですが) を表現できるので.

あと,今は一つづつファイルを示してますが,本当は,2 番目の配列を使うレベルの D ルールのフェイズから,nthprime2.dll (Windows 環境の場合) まで一発で自動生成されます.ETI の上で実行している上,私の部分評価とかバックエンドの実装がテキトーすぎるので,やたら時間がかかりますが (10 〜 15 秒ぐらい ?).

計ってみた.

[D]>(expand "nthprime.eti" "nthprime.c" "nthprime2.dll")
-------------------------D execution ---------------------
----------------------------------------------------------
succeeded.
(expand "nthprime.eti" "nthprime.c" "nthprime2.dll")
execution time: 7695 [msec]

あんまり信用できませんが,とりあえず 10 秒弱くらい ? やっぱり遅いなぁ.

まぁ,速度はとりあえず私が辛抱すれば良いだけなので… でも 10 秒弱でも意外とストレスです.GCC とかに慣れてると,やたら遅く感じます.まぁ,インタプリタなので仕方ないのですが.

まぁ,あんまり詳しくは書けないのですが,だいたいこんなことやってますですよ,はい.大事なことは何も説明してないので,雰囲気ぐらいしか伝わらないとは思いますが.

コメント

Secret

盗んだバイクですか。
まずは免許をとらないと

> kosaki さん

そうですなぁ・・・ まず普通自動車免許しか持っていない罠.

しかも,もう 5 年間ゲーハードライバーな罠.半クラって何 ? とか思ってしまう罠.

まぁ,原チャなら何とかと思ってしまう罠.

しかし何気に道交法すら怪しい罠.二段階右折の意味が思い出せない罠.

そもそもマニュアルの意味が無い罠.別にオートマでも良かった罠.実は鍵が付いてないバイクのエンジンのかけ方がよくわからない罠.

世の中には罠がいっぱいだ.みんな気をつけようぜ.

(罠に詳しい管理人)

夜更かしはいけません。

特に夏休みは生活が不規則になりがちですから、9時までには就寝できるように、ご父兄もご協力とご注意をお願いします。と書いてある。(なんに?)

> m-hiyama さん

講義が無くなったとたん,ここまで一気に生活が不規則になる,自分の自制心の無さにびっくりです.

小学生からやり直した方が良いのかもしれません・・・ 夏休みの友は,エネミーオブサマーバケーションだと未だに思っています.

朝顔に毎日水をやって育て上げて,最終的には花を搾って布を染めたり,ラジオ体操に付き合ったり,お父さんはいろいろ大変ですよね.漢字の書取りは奇門なので,早めに終らせた方が良いとお子様によろしくお伝えください.ただダラダラと書くだけではなく,ちゃんと漢字の構成などを意識しつつ書いていかないと,身につきませんよ.

私は,漢字だけを全部書いた後,読み方を書くと言う手法を持ちいたりと,いろいろ不毛な夏休みを送ってしまったので,未だにあんまり漢字が書けません.あれから 10 余年も経っているにもかかわらず,因果の鎖とは恐ろしいものです.小学生ぐらいの習慣は一生付いて回ります.この時期にドリルなどの反復学習により身につけた,数字に対する数学的感覚などは,今後の人生において非常に大切になってきますので,いろいろなことをしっかり脳に刻みつけておいてください.このように,人間としての自立性・社会性を身につける大事な時期ですので,何卒ご父兄もお子様の将来についての意識をしっかりとお持ちになり,ご協力とご注意をよろしくお願いします.

21 時のほうではなく,本当に「 *9 時* までには就寝」だったら余裕なのですが w

昨日は 12 時半,今日は 11 時半に起きました (駄目)

この調子で,毎日 1 時間ずつ起きる時間を早くしていけば,理論上はあと 4 日で元に戻るはずです.

たまにスタンド攻撃を受けて,気がつくと 14 時だったりもするわけですが.時が ! 気をつけろ,今,時が 12 時間ほどふっ飛んだぞォオオオオオ !! キングクリムゾン ! (JOJO ネタ)B

いい教訓

> 朝顔に毎日水をやって育て上げて,[...] ご協力とご注意をよろしくお願いします.
この部分コピーして、28ポイントくらいで印刷して壁に貼っておくね。

> 理論上はあと 4 日で元に戻るはずです.
うん、一日の時刻は、Z/24Zでサイクリックですから大丈夫。
プロフィール
  • Author:あろは (alohakun)
  • 京都のデバッガベンダーに勤めるアラサー会社員。

    本ブログの内容は,あくまでも個人的な感想や意見であり,会社の意見を代表するものでは一切ありません.

    連絡先 : alohakun ___at___ gmail.com
    mixi : http://mixi.jp/show_friend.pl?id=182927
    twitter : http://twitter.com/alohakun













    あわせて読みたい


    この日記のはてなブックマーク数


    スカウター : ホワット・ア・ワンダフル・ワールド


    Map
FC2カウンター
ブロとも申請フォーム

この人とブロともになる

最近のコメント
リンク
最近のトラックバック
人生の残り日数
日本人男性の平均寿命は 28700日.
RSSフィード
カテゴリー
  1. RSSリーダー