kb84tkhrのブログ

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

Reasoned Schemer (20) 足し算、引き算、整数

(defrel (+o n m k) (addero 0 n m k))

これは当然

(defrel (-o n m k) (+o m k n))

なるほどね
関係プログラミングっぽい!

(defrel (lengtho l n)
  (conde
    ((nullo l) (== '() n))
    ((fresh (d res)
       (cdro l d)
       (+o '(1) res n))
       (lengtho d res))))

からの

> (run 3 q (lengtho q q))
(() (1) (0 1))
> (run 4 q (lengtho q q))

一瞬対角線論法みたいでおもしろいと思ったけど、そんなに深い意味はないかな?どうかな?

  • `(,sign-bit . ,n)という形で整数を表すことにして、整数の足し算sumo作ってみ?
  • 正が0、負は1、0の表現は()
  • 難しそうだからランチのあとでやります

こうかなあ?
gen-sumoでnsとmsが異なる、っていう条件を書く方法が思いつかなくてちょっと悔しい形になった
condeは上から順に見ていくとは言え、元は単なるorだから・・・
ほんとのelseを書く方法はないのかなあ

(defrel (sumo n m k)
  (conde
    ((== '() n) (== m k))
    ((== '() m) (== n k))
    ((fresh (ns nn ms mn)
       (== `(ns . nn) n)))
       (== `(ms . mn) m)))
       (gen-sumo ns nn ms mn k)))))

(defrel (gen-sumo ns nn ms mn k))
  (conde
    ((== ns ms)
       (fresh (res)
         (== (+o nn mn) res)
         (== `(ns . res) k))
    ((== ns 0) (== ms 1) 
       (diff-sign-sumo ns nn ms mm k))
    ((== ns 1) (== ms 0) 
       (diff-sign-sumo ns nn ms mm k))

(defrel (diff-sign-sumo ns nn ms mm k))
  (fresh (res)
    (conde
      ((-o nn mn res) (== `(ns . res) k)))
      ((-o mn nn res) (== `(ms . res) k))))))

大小を比較する関係を定義しないといけないかと思ったけど
引き算の答えがあるかどうかだから両方引き算してみればいいんだよね?ね?
関係プログラミングっぽく書けたと思ってるんだけど!