ストリームを使ったアパート問題
これでいいのかな?
ストリームを使ったアパート問題のプログラムは以下のようになった.リスト版の決定性計算版よりはるかに遅いので,てっきり間違っていると考えたが,solveからはすぐに戻っているところをみると,動いているのかな?
しかし,全解探索するより遅いなんて….効率を何も考えずに書いているからだろうか….
(define (stream-filter-map f l) (stream-delay (stream-filter identity (stream-map f l)))) (define solve (lambda () (stream-delay (stream-filter-map (lambda (floor) (let* ((floor (stream->list floor)) (baker (first floor)) (cooper (second floor)) (fletcher (third floor)) (miller (fourth floor)) (smith (fifth floor))) (and (not (= baker 5)) (not (= cooper 1)) (and (not (= fletcher 5)) (not (= fletcher 1))) (> miller cooper) (not (= 1 (abs (- smith fletcher)))) (not (= 1 (abs (- cooper fletcher)))) (name-value baker cooper fletcher miller smith)))) (stream-permutations (stream-iota 5 1))))))
非決定性計算とストリーム
ストリームって,探索木をフラットなリストに変換したようなもので,探索木をトラバースするのとストリームから解を1つずつ取り出すのって,実は等価だったりするのかな? 任意の非決定性計算はストリームを使って書き直せて,逆も可能なのだろうか?
とりあえず,下のintegers-from-nは等価じゃないかな.
(define (integers-from-n n) (stream-delay (stream-cons n (integers-from-n (+ n 1)))))
integers_from_n(N,N) :- integer(N). integers_from_n(N,N2) :- N1 is N + 1, integers_from_n(N1,N2).
次のprimesも等価な気がするが,本当かな….
(define (divisible? x y) (zero? (remainder x y))) (define (sieve stream) (stream-delay (stream-cons (stream-car stream) (sieve (stream-filter (lambda (x) (not (divisible? x (stream-car stream)))) (stream-cdr stream)))))) (define primes (sieve (integers-from-n 2)))
:- dynamic prime/1. non_prime(N) :- prime(P), P < N, N mod P =:= 0. primes(N) :- integers_from_n(2,N), not(non_prime(N)), assert(prime(N)).
このProlog版エラトステネスのふるいは,assert/1を使うところがいかにもPrologらしくていいな.SiroKuroさんのプログラムをちょっと書き換えさせてもらったものだ.SiroKuroさんのは,ある上限値までの素数を表示するプログラムで,こちらは,?-primes(N)と質問すると,セミコロンを入力する限り,素数を返し続けるというふるまいをする.