Reasoned Schemer (006) (Schemeからの)翻訳
nullo
は見たまんま
(defrel (nullo x)
(== '() x))
なんだけどじーっと見てるとわからなくなってきたり
これは#s
とか#u
とか返すやつ
pairo
もやることは見たまんまなんだけど定義にはconso
を使う
(defrel (pairo p)
(fresh (a d) (conso a d p)))
Is
pairo
recursive?
そうか、nullo
が出てきたということは再帰が出てくるってことか
- singletonは要素が一つのリスト
(define (singleton? l)
(cond ((pair?l) (null? (cdr l)))
(else #f)))
これは普通の関数
- リストがプロパーであるとは、空リストか、cdrがプロパーであるペアであること
日本語にするのはあきらめた
singleton?
をsingletono
に翻訳するには、else
を#t
に置き換えておく必要がある
ふむ
翻訳(最初の版)
関数を関係に翻訳するには、まずdefine
をdefrel
に置き換える。次に、ひとつひとつのcond
行をunnestし、cond
をconde
に置き換える。#t
は#s
に、#f
は#u
にunnnestする。
else
を#t
にしておくのは、ルールを減らしたい、くらいのことかな
翻訳したもの
(defrel (singletono l)
(conde ((pairo l)
(fresh (d)
(cdro l d)
(nullo d)))
(#s #u)))
#u
の掟
トップレベルのゴールに#u
があるconde
行は値に貢献しない
とか使って簡単にすると
(defrel (singletono l)
(fresh (d)
(cdro l d)
(nullo d)))
論理脳になればこういう表現が先に出てくるんだろうな
っていうかこれくらいならSchemeで書いて翻訳するより自分で1から考えたほうが速いか
最初にSchemeで作ってから翻訳するっていう書き方を推奨しているわけではあるまい
同じことが書けるよ!って言いたいんだろう
caro
とcdro
をconso
で定義せよ
(defrel (caro p a)
(fresh (d) (conso a d) p))
(defrel (cdro p d)
(fresh (a) (conso a d) p))
でいいかな?
せっかく翻訳の手順教えてもらったのにこれっぽっちも生かしていませんが
いいのか?