構文木が文法的に正しく出力されるようにする3(if文正常出力成功)
【内部主要記事】
if文が通常の使われ方をするようにコードを出力することに成功しました。
(use math.mt-random) (define mt (make <mersenne-twister> :seed (sys-time))) (define terminal (lambda () (let ((rdm (mt-random-integer mt 26) )) (string-ref "abcdefghijklmnopqrstuvwxyz" rdm)))) (define non-terminal (lambda () (let ((rdm (mt-random-integer mt 2) )) (cond ;((eq? rdm 0) 'car) ;((eq? rdm 1) 'cdr) ((eq? rdm 0) 'cons) (else 'if))))) ;(eq? rdm 3) 'quote) ;((eq? rdm 3) 'if) ;((eq? rdm 4) 'define) ;((eq? rdm 4) 'eq?) ;(else 'list?))))) (define atom? (lambda (atom) (if (pair? atom) #f #t))) (define argument-map (lambda () (list ;(cons 'car 1) ;(cons 'cdr 1) ;(cons 'list? 1) (cons 'cons 2) (cons 'eq? 2) (cons 'atom? 1)))) (define if-eq '(if (eq?))) (define allowable-depth 5) ;const (define full-p #t) ;const (define top-node-p #f) ;const (define eq?-or-atom? (lambda () (let ((ea (mt-random-integer mt 2) )) (cond ((eq? ea 0) 'eq?) ((eq? ea 1) 'atom?))))) ; 指定された関数および終端記号を再帰的に使用して、プログラムを ; 作成します。argument-mapは、関数セットにおける各関数が ; いくつの引数を持つべきかを決定するのに使用されます。 ; allowable-depthさは私たちが作成することができる木の残りの ; 深さであり、0がヒットした時は、単体の終端記号を選択します。 ; 私たちが木のトップのノードとして呼ばれている場合に限り、 ; top-node-pは真です。これは、常に木の一番上に関数を置いた ; ことを私たちが確かめることを可能にします。 ; full-pは、最高に枝が多い個体かどうかを示します。 (define create-individual-program (lambda (allowable-depth top-node-p full-p) (cond ((<= allowable-depth 0) ;; 最深に到達。よって終端記号を選択する。 (terminal)) ((or full-p top-node-p) ;; top-node-p か full-p を満たした。 ;; よって非終端記号(関数)だけを選択する。 (let ((choice (non-terminal))) ; if が選択されたら eq? か list? を cons し ; choice を eq? か list? に変換する。 (cond ((eq? 'if choice) (let ((eq-or-atom (mt-random-integer mt 2) )) (define choice (cond ((eq? eq-or-atom 0) 'eq?) ((eq? eq-or-atom 1) 'atom?))) (let ((number-of-arguments (cdr (assq choice (argument-map))))) ;(set! allowable-depth (- allowable-depth 2)) (list 'if (cons choice (create-arguments-for-function number-of-arguments (- allowable-depth 1) full-p)) (terminal) (terminal) )))) ; choiceがif以外の場合。 (else (let ((number-of-arguments (cdr (assq choice (argument-map))))) (cons choice (create-arguments-for-function number-of-arguments (- allowable-depth 1) full-p))))))) (else ;; 非終端記号(関数)か終端記号から1つ選ぶ。 ;0 or 1 でまず2択にしてから関数を呼ぶ (let ((set (mt-random-integer mt 2) )) (let ((choice (cond ((eq? set 0) (terminal)) ((eq? set 1) (non-terminal)) ) )) (cond ((eq? set 1) ;; 非終端記号(関数)を選び、ここから下へ木を作成し続ける。 (let ((function choice) (number-of-arguments (cdr (assq choice (argument-map))))) (cons function (create-arguments-for-function number-of-arguments (- allowable-depth 1) full-p)))) ;; atomを選ぶ (else (terminal)) ) )))))) ; ツリーのノード用の引数のリストを作成します。 ; 引数の数は、今から作成される残りの引数の数です。 ; 各引数は、create-individual-programを ; 使用することで正常な方法で作成されます。 (define create-arguments-for-function (lambda (number-of-arguments allowable-depth full-p) (cond ((eq? number-of-arguments 0) ()) (else (cons (create-individual-program allowable-depth () full-p) (create-arguments-for-function (- number-of-arguments 1) allowable-depth full-p))))))
以下に実行例を示します。
gosh> (load "./random-tree.scm") #t ;;ランダムなプログラム出力 gosh> (create-individual-program allowable-depth top-node-p full-p) (cons (cons (if (eq? (if (atom? (cons #\d #\e)) #\a #\s) (if (eq? (cons #\h #\t) (if (atom? #\e) #\x #\u)) #\a #\p)) #\e #\u) (if (eq? (cons (cons #\i #\h) (cons #\m #\q)) (if (eq? (if (eq? #\g #\o) #\k #\y) (cons #\g #\y)) #\b #\o)) #\t #\c)) (cons (if (eq? (cons (cons #\s #\b) (if (eq? #\j #\b) #\b #\x)) (if (atom? (if (eq? #\n #\o) #\h #\d)) #\h #\u)) #\i #\v) (cons (cons (if (eq? #\i #\u) #\e #\t) (cons #\g #\m)) (cons (cons #\c #\t) (cons #\g #\t))))) ;;出力されたランダムなプログラムの実行 gosh> (cons (cons (if (eq? (if (atom? (cons #\d #\e)) #\a #\s) (if (eq? (cons #\h #\t) (if (atom? #\e) #\x #\u)) #\a #\p)) #\e #\u) (if (eq? (cons (cons #\i #\h) (cons #\m #\q)) (if (eq? (if (eq? #\g #\o) #\k #\y) (cons #\g #\y)) #\b #\o)) #\t #\c)) (cons (if (eq? (cons (cons #\s #\b) (if (eq? #\j #\b) #\b #\x)) (if (atom? (if (eq? #\n #\o) #\h #\d)) #\h #\u)) #\i #\v) (cons (cons (if (eq? #\i #\u) #\e #\t) (cons #\g #\m)) (cons (cons #\c #\t) (cons #\g #\t))))) ;;実行結果 ((#\u . #\c) #\v (#\t #\g . #\m) (#\c . #\t) #\g . #\t)