sicp 4.4.1小节习题

简介:
本节开始进入第4章最后一部分——逻辑程序设计。scheme将实现一种查询语言,非常类似prolog。由于解释器的实现在后面,还未读到,前面的习题我都将用prolog做测试,当然也给出scheme版本的解答,待以后测试。
    首先给出依照书中所述写出的prolog事实库:
address( ' BitDiddle Ben ' , ' Slumerville ' , ' Ridge Road ' , 10 ).
address(
' Hacker Alyssa P ' , ' Cambridge ' , ' Mass Ave ' , 78 ).
address(
' Fect Cy D ' , ' Cambridge ' , ' Ames Street ' , 3 ).
address(
' Tweakit Lem E ' , ' Boston ' , ' Bay State Road ' , 22 ).
address(
' Reasoner Louis ' , ' Slumerville ' , ' Pine Tree Road ' , 80 ).
address(
' Warbucks Oliver ' , ' Swellesley ' , ' Top Heap Road ' ,unknown).
address(
' Scrooge Eben ' , ' Weston ' , ' Shady Lane ' , 10 ).
address(
' Aull DeWitt ' , ' Slumerville ' , ' Onione Square ' , 5 ).
address(
' Cratchet Robert ' , ' Allston ' , ' N Harvard Street ' , 16 ).


job(
' BitDiddle Ben ' ,computer,wizard).
job(
' Hacker Alyssa P ' ,computer,programmer).
job(
' Fect Cy D ' ,computer,programmer).
job(
' Tweakit Lem E ' ,computer,technician).
job(
' Warbucks Oliver ' ,administration, ' big wheel ' ).
job(
' Scrooge Eben ' ,accounting, ' chief accountant ' ).
job(
' Aull DeWitt ' ,administration,secretary).
job(
' Cratchet Robert ' ,accounting,scrivener).
job(
' Reasoner Louis ' ,computer,programmer,trainee).

salary(
' Hacker Alyssa P ' , 40000 ).
salary(
' BitDiddle Ben ' , 60000 ).
salary(
' Fect Cy D ' , 35000 ).
salary(
' Tweakit Lem E ' , 25000 ).
salary(
' Reasoner Louis ' , 30000 ).
salary(
' Warbucks Oliver ' , 150000 ).
salary(
' Scrooge Eben ' , 75000 ).
salary(
' Cratchet Robert ' , 18000 ).
salary(
' Aull DeWitt ' , 25000 ).

supervisor(
' Hacker Alyssa P ' , ' BitDiddle Ben ' ).
supervisor(
' Fect Cy D ' , ' BitDiddle Ben ' ).
supervisor(
' Tweakit Lem E ' , ' BitDiddle Ben ' ).
supervisor(
' Reasoner Louis ' , ' Hacker Alyssa P ' ).
supervisor(
' BitDiddle Ben ' , ' Warbucks Oliver ' ).
supervisor(
' Scrooge Eben ' , ' Warbucks Oliver ' ).
supervisor(
' Cratchet Robert ' , ' Scrooge Eben ' ).
supervisor(
' Aull DeWitt ' , ' Warbucks Oliver ' ).

can_do(computer,wizard,computer,programmer).
can_do(computer,wizard,computer,technician).
can_do(administration,secretary,administration,
' big wheel ' ).

习题4.55开始,
1)所有被Ben BitDiddle管理的人:
(supervisor ?x (BitDiddle Ben))
prolog测试:
|  ? -  supervisor(Name, ' BitDiddle Ben ' ).

Name 
=   ' Hacker Alyssa P '  ? ;

Name 
=   ' Fect Cy D '  ? ;

Name 
=   ' Tweakit Lem E '  ? ;

no

2)会计部所有的人的名字和工作:
(job ?name (accounting .?type))

prolog测试:
|  ? -  job(Name,accounting,Type).

Name 
=   ' Scrooge Eben '
Type 
=   ' chief accountant '  ? ;

Name 
=   ' Cratchet Robert '
Type 
=  scrivener

yes

3)在Slumerville居住所有人的名字和地址:
(address ?name (Slumerville ?where))

prolog测试:
|  ? -  address(Name, ' Slumerville ' ,Road,No).

Name 
=   ' BitDiddle Ben '
No 
=   10
Road 
=   ' Ridge Road '  ? ;

Name 
=   ' Reasoner Louis '
No 
=   80
Road 
=   ' Pine Tree Road '  ? ;

Name 
=   ' Aull DeWitt '
No 
=   5
Road 
=   ' Onione Square '  ? ;

习题4.56
1)给出Ben Bitdiddle的所有下属的名字,以及他们的地址:
( and
  (supervisor ?name (Bitdiddle Ben))
  (address ?name ?where))
prolog测试,注意prolog是用,号表示and的关系:

|  ? -  supervisor(Name, ' BitDiddle Ben ' ),address(Name,City,Road,No).

City 
=   ' Cambridge '
Name 
=   ' Hacker Alyssa P '
No 
=   78
Road 
=   ' Mass Ave '  ? ;

City 
=   ' Cambridge '
Name 
=   ' Fect Cy D '
No 
=   3
Road 
=   ' Ames Street '  ? ;

City 
=   ' Boston '
Name 
=   ' Tweakit Lem E '
No 
=   22
Road 
=   ' Bay State Road '  ? ;

2)所有工资少于Ben Bitdiddle的人,以及他们的工资和Ben Bitdiddle的工资
( and  
   (salary (Bitdiddle Ben) ?ben)
   (salary ?person ?amount)
  
(lisp - value  <  ?amount ?ben)
   )

prolog测试:
?-salary( ' BitDiddle Ben ' ,Bensalary),salary(Person,Amount),Amount < Bensalary.

Amount 
=   40000
Bensalary 
=   60000
Person 
=   ' Hacker Alyssa P '  ? ;

Amount 
=   35000
Bensalary 
=   60000
Person 
=   ' Fect Cy D '  ? ;

Amount 
=   25000
Bensalary 
=   60000
Person 
=   ' Tweakit Lem E '  ? ;

Amount 
=   30000
Bensalary 
=   60000
Person 
=   ' Reasoner Louis '  ? ;

Amount 
=   18000
Bensalary 
=   60000
Person 
=   ' Cratchet Robert '  ? ;

Amount 
=   25000
Bensalary 
=   60000
Person 
=   ' Aull DeWitt '

3)所有不是由计算机分部的人管理的人,以及他们的上司和工作:
( and  (supervisor ?person ?boss)
     (
not  (job ?boss (computer . ?type)))
     (job ?boss?bossjob))

prolog测试:
|  ? -  supervisor(Person,Boss),\ + (job(Boss,computer,_)),job(Boss,BossJob1,BossJob2).

Boss 
=   ' Warbucks Oliver '
BossJob1 
=  administration
BossJob2 
=   ' bit wheel '
Person 
=   ' Ben BitDiddle '  ? ;

Boss 
=   ' Warbucks Oliver '
BossJob1 
=  administration
BossJob2 
=   ' bit wheel '
Person 
=   ' Scrooge Eben '  ? ;

Boss 
=   ' Scrooge Eben '
BossJob1 
=  accounting
BossJob2 
=   ' chief accountant '
Person 
=   ' Cratchet Robert '  ? ;

Boss 
=   ' Warbucks Oliver '
BossJob1 
=  administration
BossJob2 
=   ' bit wheel '
Person 
=   ' Aull DeWitt '

习题4.57
定义这个规则,用scheme实现是:
(rule (instead ?person ?insteadperson )
    (
and  
       (job ?person ?insteadedjob)
       (job ?insteadperson ?job)
       (
not  (same ?person ?insteadperson))
       (
or  (can - do - job ?job ? insteadedjob )
           (same ?job ?
insteadedjob ))))
         

用prolog定义此规则:
instead(Person,InsteadPerson): -
   job(Person,Part,Pos),
   job(InsteadPerson,InsteadPart,InsteadPos),
   Person\
== InsteadPerson,
 (can_do(InsteadPart,InsteadPos,Part,Pos);InsteadPart
== Part,InsteadPos == Pos).

a)找出能代替Cy D.Fect的人:
(instead (Fect Cy D) ?person)
prolog测试:
|  ? -  instead( ' Fect Cy D ' ,InsteadPerson).

InsteadPerson 
=   ' BitDiddle Ben '  ? ;

InsteadPerson 
=   ' Hacker Alyssa P '  ? ;

b)找出所有能够代替某个工资比自己高的人的人,以及两个人的工资:
( and  (?person1 ?person2)
     (salary ?person1 ?salary1)
     (salary ?person2 ?salary2)
     (lisp
- value  >  ?salary1 ?salary2))

prolog测试:
|  ? -  instead(Person1,Person2),salary(Person1,Salary1),salary(Person2,Salary2),Salary1 > Salary2.

Person1 
=   ' Hacker Alyssa P '
Person2 
=   ' Fect Cy D '
Salary1 
=   40000
Salary2 
=   35000  ? ;

Person1 
=   ' Warbucks Oliver '
Person2 
=   ' Aull DeWitt '
Salary1 
=   150000
Salary2 
=   25000  ? ;

习题4.58
(rule (vip ?person)
   (
and
       (job ?person (?part .?pos))
       (
or
           (
not  (supervisor ?person ?boss))
           (
and
                (?boss (?bosspart .?bosspos))
                (
not  (same ?part ?bosspart))))))

用prolog实现并测试的结果:
vip(Person): -
  job(Person,Part,Pos),
  (\
+ (supervisor(Person,Boss));
   (supervisor(Person,Boss),
   job(Boss,BossPart,_),
   Part\
== BossPart)).

|  ? -  vip(Person).

Person 
=   ' BitDiddle Ben '  ? a

Person 
=   ' Warbucks Oliver '

Person 
=   ' Scrooge Eben '

习题4.59,增加4个事实到prolog程序中:
meeting(accounting,monday,am9).
meeting(administration,monday,am10).
meeting(computer,wednesday,pm3).
meeting(administration,friday,pm1).
meeting(whole
- company,wednesday,pm4).

a)查询星期五的会议,scheme实现:
(meeting ?part (Friady ?time))
prolog实现并测试:
|  ? -  meeting(Part,friday,Time).

Part 
=  administration
Time 
=  pm1 ? ;


b)scheme实现查询规则:
(rule (meeting - time ?person ?day - and - time)
        (
or  (meeting whole - company ?day - and - time)
            (
and
              (job ?person (?part . ?r))
              (meeting ?part ?day
- and - time))))

prolog实现并测试
meeting_time(Person,Day,Time): -
    meeting(whole
- company,Day,Time);
    (job(Person,Part,_),meeting(Part,Day,Time)).

|  ? -  meeting_time( ' BitDiddle ' ,Day,Time).

Day 
=  wednesday
Time 
=  pm4 ? ;

no
|  ? -  meeting_time(Person,friday,Time).

Person 
=   ' Warbucks Oliver '
Time 
=  pm1 ? ;

Person 
=   ' Aull DeWitt '
Time 
=  pm1 ? ;

c)Alyssa周三参加的会议:
(meeting - time (Hacker Alyssa P) (Wednesday ?time))
prolog测试:
|  ? -  meeting_time( ' Hacker Alyssa P ' ,wednesday,Time).

Time 
=  pm4 ? ;

Time 
=  pm3

习题4.60,会重复是因为person1和person2都是查询所有的address,而lives-near只规定
(not (same person1 person2))
而没有定义两者的顺序,因此解决办法就是强制加入一个固定顺序即可去除重复,通过string>来比较两个字符串。解释器还未实现,具体怎么写留待后面,原理就是这样了。

习题4.62,猜测实现如下,模式匹配,递归实现:
(rule (last - pair (?x) (?x)))
(rule (last
- pair (?v . ?u) (?z))
      (last
- pair ?u (?z))


习题4.63
,这一题很简单了,按照题意翻译过来就是:

(rule (grandson ?g ?s)
          (
and
            (son ?g ?f)
            (son ?f ?s)))
(rule (son ?m ?s)



(and



(wife ?m ?w)



(son ?w ?s)))


看看prolog怎么解决:
son(adam,cain).
son(cain,enoch).
son(enoch,irad).
son(irad,mehujael).
son(mehujael,methushael).
son(methushael,lamech).
son(ada,jabal).
son(ada,jubal).
wife(lamech,ada).
son2(M,S):
-
   wife(M,W),
   son(W,S).
grandson(G,S):
-
   son(F,S),
   son(G,F).


测试一下:
|  ? -  son2(lamech,jabal).

true ? ;

|  ? -  son2(lamech,jubal).

yes

|  ? -  grandson(adam,enoch).

true ? ;
文章转自庄周梦蝶  ,原文发布时间2008-11-22
目录
相关文章
|
6月前
|
C语言
C程序设计内容与例题讲解 -- 第四章--选择结构程序设计(第五版)谭浩强
C程序设计内容与例题讲解 -- 第四章--选择结构程序设计(第五版)谭浩强
117 1
|
6月前
|
存储 移动开发 C语言
# C程序设计内容与例题讲解 -- 第三章第一部分(第五版)谭浩强
# C程序设计内容与例题讲解 -- 第三章第一部分(第五版)谭浩强
|
6月前
|
C语言 数据格式
C程序设计内容与例题讲解 -- 第三章第三部分(第五版)谭浩强
C程序设计内容与例题讲解 -- 第三章第三部分(第五版)谭浩强
|
6月前
|
存储 C语言
C程序设计内容与例题讲解 -- 第三章第二部分(第五版)谭浩强
C程序设计内容与例题讲解 -- 第三章第二部分(第五版)谭浩强
|
5月前
|
IDE 编译器 开发工具
详细解读C语言程序设计:现代方法(第2版)第二章全部习题答案
详细解读C语言程序设计:现代方法(第2版)第二章全部习题答案
42 0
|
6月前
|
C语言
C程序设计内容与例题讲解 -- 第四章--选择结构程序设计第二部分(第五版)谭浩强
C程序设计内容与例题讲解 -- 第四章--选择结构程序设计第二部分(第五版)谭浩强
|
机器学习/深度学习 存储 人工智能
C语言程序设计第五版谭浩强课后答案 第五章习题答案(3-17题)
C语言程序设计第五版谭浩强课后答案 第五章习题答案(3-17题)
|
存储 编译器 程序员
第八章 数组《C语言程序设计现代方法(第2版)》读书笔记
我们所见的变量都只是 标量(scalar ):标量具有保存单一数据项的能力。C语言也支持 聚合 (aggregate )变量,这类变量可以存储一组一组的数值。在 C 语言中一共有两种聚合类型: 数组 (array)和结构(structure )。
第八章 数组《C语言程序设计现代方法(第2版)》读书笔记
|
Java
java编程思想第四版第十一章习题
运行结果分析: 这个案例的重点是, 数组瘦受限制的, 集合是没有元素个数限制的。
212 0