这次回顾第四章第七部分习题,最后一部分的源码难度较大,所以先忽略后续习题。

学习资料:

https://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-001-structure-and-interpretation-of-computer-programs-spring-2005/index.htm

https://github.com/DeathKing/Learning-SICP

https://mitpress.mit.edu/sites/default/files/sicp/index.html

https://www.bilibili.com/video/BV1Xx41117tr?from=search&seid=14983483066585274454

参考资料:

https://sicp.readthedocs.io/en/latest

http://community.schemewiki.org/?SICP-Solutions

http://community.schemewiki.org/?sicp

https://liujiacai.net/blog/2016/02/22/recursion-without-name/

https://mvanier.livejournal.com/2897.html

https://github.com/jiacai2050/sicp

https://liujiacai.net/

4.64(p323)

调用过程:

(outranked-by (Bitdiddle Ben) ?boss)
(outranked-by (Bitdiddle Ben) ?boss)
(outranked-by (Bitdiddle Ben) ?boss)
......

4.65(p323)

层级关系如下:

(supervisor (Bitdiddle Ben) (Warbucks Oliver))
(supervisor (Hacker Alyssa P) (Bitdiddle Ben))

(supervisor (Bitdiddle Ben) (Warbucks Oliver))
(supervisor (Fect Cy D) (Bitdiddle Ben))

(supervisor (Bitdiddle Ben) (Warbucks Oliver))
(supervisor (Tweakit Lem E) (Bitdiddle Ben))

(supervisor (Scrooge Eben) (Warbucks Oliver))
(supervisor (Cratchet Robert) (Scrooge Eben))

(supervisor (Aull DeWitt) (Warbucks Oliver))

所以会出现$4$次。

4.66(p324)

结果可能会重复出现,如下查询会产生重复结果:

(sum ?amount
     (and (wheel ?x)
          (salary ?x ?amount)))

解决方法是删除重复项。

4.67(p324)

对每个规则,维护使用过的(参数,值)构成的字典;每次调用规则时,首先查看当前参数是否在字典中,如果在参数表中,则直接返回对应的值即可;否则将(参数,NULL)插入字典,然后对该参数调用规则,结束后将对应的值更新至字典中。

4.68(p324)

尝试了两种规则,无法匹配全部情形:

; v1
(rule (reverse () ()))

(rule (reverse (?u . ?v) ?y)
      (and (reverse ?v ?z)
           (append-to-form ?z (?u) ?y)))

; v2
(rule (reverse1 () ()))

(rule (reverse2 () ()))

(rule (reverse1 (?u . ?v) ?y)
      (and (reverse1 ?v ?z)
           (append-to-form ?z (?u) ?y)))

(rule (reverse2 ?y (?u . ?v))
      (and (reverse2 ?z ?v)
           (append-to-form ?z (?u) ?y)))

(rule (reverse ?x ?y)
      (or (reverse1 ?x ?y)
          (reverse2 ?x ?y)))

4.69(p325)

参考资料:

http://community.schemewiki.org/?sicp-ex-4.69

规则:

(define db2
  '(
    (son Adam Cain)
    (son Cain Enoch)
    (son Enoch Irad)
    (son Irad Mehujael)
    (son Mehujael Methushael)
    (son Methushael Lamech)
    (wife Lamech Ada)
    (son Ada Jabal)
    (son Ada Jubal)

    (rule (son? ?x ?y)
          (or (son ?x ?y)
              (and (wife ?z ?x)
                  (son ?z ?y))
              (and (wife ?x ?z)
                  (son ?z ?y))))

    (rule (grandson? ?x ?y)
          (and (son? ?x ?z)
              (son? ?z ?y)))

    (rule (append-to-form () ?y ?y))

    (rule (append-to-form (?u . ?v) ?y (?u . ?z))
          (append-to-form ?v ?y ?z))

    ; 4.69
    (rule (end-with-grandson (grandson?)))

    (rule (end-with-grandson (?x . ?y))
          (end-with-grandson ?y))

    (rule ((grandson?) ?x ?y)
          (grandson? ?x ?y))

    (rule ((great . ?rel) ?x ?y)
          (and (son? ?x ?z)
               (?rel ?z ?y)
               (end-with-grandson ?rel)))
))

测试:

(load "ch4-query.scm")

(initialize-data-base db2)
(query-driver-loop)

((great grandson?) ?g ?ggs) 

((great . ?rel) ?x ?y)

(?relationship Adam Irad)

结果:

;;; Query input:
((great grandson?) ?g ?ggs)
;;; Query results:
((great grandson?) mehujael jubal)
((great grandson?) irad lamech)
((great grandson?) mehujael jabal)
((great grandson?) enoch methushael)
((great grandson?) cain mehujael)
((great grandson?) adam irad)

;;; Query input:
((great . ?rel) ?x ?y)
;;; Query results:
((great grandson?) mehujael jubal)
((great great grandson?) irad jubal)
((great grandson?) mehujael jabal)
((great grandson?) irad lamech)
((great great great grandson?) enoch jubal)
((great great grandson?) irad jabal)
((great grandson?) enoch methushael)
((great great great great grandson?) cain jubal)
((great great grandson?) enoch lamech)
((great great great great great grandson?) adam jubal)
((great grandson?) cain mehujael)
((great great great grandson?) enoch jabal)
((great grandson?) adam irad)
((great great grandson?) cain methushael)
((great great grandson?) adam mehujael)
((great great great grandson?) cain lamech)
((great great great grandson?) adam methushael)
((great great great great grandson?) cain jabal)
((great great great great grandson?) adam lamech)
((great great great great great grandson?) adam jabal)

;;; Query input:
(?relationship Adam Irad)
;;; Query results:
((great grandson?) adam irad)

备注由于?rel是表,所以增加如下rule:

(rule ((grandson?) ?x ?y)
      (grandson? ?x ?y))