kb84tkhrのブログ

何を書こうか考え中です あ、あと組織とは関係ないってやつです 個人的なやつ

定理証明手習い(a0) しゅくだい(8)

想定以上に寝かせることになってしまいましたがアドバイスいただきましたので考えてみます
寝かせたわりには特にアイデアは思いついていません

さてアドバイスが雰囲気でしかわかってないので最初から考えていきます

まず逆consとはなにか
rconsと逆consは同じものでしょうからrconsと書くことにすると
(rcons '(a b) 'c)'(a b c)になるようなものでしょう
特殊ケースとして(rcons '() 'a)'(a)になる、というのはいいとして
(rcons 'a 'b)はどうなるべきでしょうか
(a . b)かな?

じゃあそれはそういうものとして
rconsというものがある、という前提に立って公理を作るのかな?
rcarとかrcdrも考えるのかな?
それともconsを使ってrconsを定義するんでしょうか

rcons、rcar、rcdrまで全部作ってしまうとそれだけで完結してしまって
cons、car、cdrの世界とのつながりがなくなってしまいそうです
それも公理でつなげてもできそうではありますが

まずはconsを使って書く方式で考えてみようと思います
まず考えたのはこれ

(defun rcons (x y)
  (if (atom x)
      (cons y x)
      (cons (car x) (rcons (cdr x) y))))

ただしこれだと(rcons 'a 'b)'(b . a)になってしまいます
'(a . b)にしようとすると場合分けになる?

(defun rcons (x y)
  (if (atom x)
      (if (equal x '())
          (cons y '())
          (cons x y))
      (cons (car x) (rcons (cdr x) y))))

yが第1引数になったり第2引数になったりするのがどうも気分がよくありません
複雑だと証明が面倒になるし最初の定義で進めてみようかな
全域にしたいから(rcons 'a 'b)にも値を持たせるけど、何を返すかは気にするな、という考え方で

rconsがあればreverseはすぐ書ける

(defun reverse (x)
  (if (atom x)
      x
      (rcons (reverse (cdr x)) (car x))))

動かす

> (reverse '())
()
> (reverse '(a))
(a)
> (reverse '(a b c))
(c b a)

よさそう
イレギュラーなケースはどうなるかな

> (reverse 'a)
a
> (reverse '(a . b))
(a . b)
> (reverse '(a b . c))
(b a . c)

reverseしてるとは言えませんがここは何か値が帰ればいいことにしておいて進みます

(dethm reverse/reverse (x)
  (equal (reverse (reverse x)) x))

成り立つか

> (reverse/reverse '())
t
> (reverse/reverse '(a))
t
> (reverse/reverse '(a b c))
t
> (reverse/reverse 'a)
t
> (reverse/reverse '(a . b))
t
> (reverse/reverse '(a b . c))
t

よさげ