课内实践 21:逻辑推理例子
•在 Windows 的开始菜单中选择安装
(Start‐>Visual Prolog‐>Install Examples)
启动 Visual Prolog
可以在安装的Examples文件夹中找到PIE工程, 在IDE中打开这个工程并执行程 序,把 PIE工程当成通常的工程来执行。在Dialogue中输入:grandfather(X, Y). 并回车显示如下界面:
• father(“Bill”, “John”).
father(“Pam”, “Bill”).
father(“Pam”, “Bill”). grandFather(GrandChild, GrandFather) :-
father(GrandChild, Father), father(Father, GrandFather).
运行结果:
• grandfather(X, Y). X = “Pam”.
Y = “John”.
X = “Pam”. Y = “John”.
2 Solutions
修改后的运行结果是? • 修改第三行的程序为:
father(“Pam”, “Bill2”).
• 然后单击Engine菜单中
的Reconsult
• 再次在Dialogue中输入: grandfather(X, Y).并回 车
修改后的运行结果:
• grandfather(X, Y). X = “Pam”.
Y = “John”.
1 Solution
使用逻辑的语言
• prolog是Programming in LOGic的缩写,意 思就是使用逻辑的语言编写程序。
• 逻辑思维在我们日常生活中比比皆是, prolog正是把这种思维用文字描述出来的计 算机语言。
2
课内实践 22:寻找情侣
寻找情侣 :
• 比如一群年轻人正在恋爱,每个人都有自己心中 所追求的对象:
张学友爱王菲
张学友爱周慧敏
王菲爱谢廷峰
周慧敏爱张学友
谢廷峰爱王菲
谢廷峰爱周慧敏
刘德华爱周慧敏
…. 我们说两个年轻人要互相都喜爱,他们就算是一 对情侣,那么上面的谁和谁是情侣呢?
• 这应该算是一道最简单逻辑推理题目了,那么我 们如何用prolog语言实现呢?
“张学友爱王菲”是一条已知的事实,用prolog语言 来表达就是:
爱(张学友,王菲).
注意1:这里是为了阅读方便才使用汉字的,真正 的prolog是不允许使用除了基本字符以外字符 的,也就是说,上面的句子必须写成 love(zhangxueyou,wanfei).,电脑才能够真正的 理解。
注意2:最末尾的“.”一定不能掉,它表示一个句子 结束。
• 注意3:上面词汇对于电脑来说并没有真正的含 义,所以我们完全可以用 ai(zxy,wf).来表达这个 关系,更进一步,我们甚至可以用 xxx(a,b).来表 达,只要你自己心里清楚xxx表示爱,a表示张学 友,b表示王菲就可以了。
注意4:张学友和王菲的顺序也没有特别的规定, 你完全可以把他们换个位置:爱(王菲,张学友). 只 要你心里清楚它表达的意思就行了,而以后都遵 循这种被爱的人在前面的顺序,就不会出错。
那么情侣的概念怎么定义呢?
• 情侣(某人甲,某人乙):-爱(某人甲,某人乙),爱(某人 乙,某人甲). :-在prolog中表示“如果”的意思,我们使用它来定义 规则。上面这句话的意思就是,某人甲和某人乙是 情侣的规则就是:某人甲爱某人乙,并且某人乙爱 某人甲。上面用来分隔两个爱的句子的“,”表示并 且的意思。 当然为了能够让电脑运行,这个句子要改为英文的:
lovers(X,Y):-love(X,Y),love(Y,X).
• 注意:在prolog中以小写字符开头的字符串代表确 知的事物,比如love表示爱这种关系,而 zhangxueyou表示张学友。而以大写字母开头的字 符串表示未确定的事物,翻译成汉语就是某某。
完整的可运行的prolog程序如下:
• love(zhangxueyou,wanfei). love(zhangxueyou,zouhuimin). love(wanfei,xietinfen). love(zouhuimin,zhangxueyou). love(xietinfen,wanfei). love(xietinfen,zouhuimin). love(liudehua,zouhuimin). lovers(X,Y):-love(X,Y),love(Y ,X).
如何运行?
• 在Dialogue中输入 love(zhangxueyou,wanfei). 表示询问机器:张学友爱王菲么?
4
练习1:写下面的询问代码: 1. 如果要询问的是:张学友爱刘德华
吗?
• 如何来写代码?运行结果是什么?
2. 如果要询问的是:张学友都喜欢哪些 人?
• 如何来写代码?运行结果是什么?
练习1:代码提示
1. love(zhangxueyou,liudehua).
• 这句话询问的是:张学友爱刘德华吗?
• 解释器将给出答案: No solutions
2. love(zhangxueyou,X).
• 这句话询问的是:张学友都喜欢哪些人?解释器
将给出答案:
X = “wanfei”.
X = “zouhuimin”.
练习2:写下面的询问代码:
1. 如果要询问的是:哪些人爱周慧敏? • 如何来写代码?运行结果是什么?
5
练习3:如何询问谁彼此是恋人?
• lovers(X,Y).
X = “zhangxueyou”. Y = “zouhuimin”.
X = “wanfei”. Y = “xietinfen”.
X = “zouhuimin”.
Y = “zhangxueyou”.
X = “xietinfen”. Y = “wanfei”.
4 Solutions
练习4:如何询问王菲的恋人是谁? • lovers(wanfei,Y).
Y = “xietinfen”. 1 Solution
练习5:编写一个寻找情敌的规则 :
• Y是X的情敌的条件是:X喜欢Z(代表某个 人),而Z不喜欢X,而Y是Z喜欢的人。
练习5:运行结果
• rival_in_love(X,Y). X = “zhangxueyou”. Y = “xietinfen”.
X = “xietinfen”.
Y = “zhangxueyou”.
X = “liudehua”.
Y = “zhangxueyou”.
3 Solutions
6
拓展练习:
1. “所有的人(person)都会死(mortal)”
写出 prolog 规则,并且加入事实:苏格拉底是一个人,询问机器苏格拉底是否会死?
2. 识别动物
白鹭是鸟。
鹰是动物。
鹰有羽毛。
“如果 X 是动物,并且 X 有羽毛,则 X 是鸟” 提问:鹰是否是鸟?白鹭是否有羽毛?
3. 买车
有 tom,john,tina 三个人。有 polo,jeta,tena,benz 四种车
3. 在售的车有jeta,benz。tom喜欢polo和benz,john喜欢polo和jeta,tina喜欢tena和benz, 问题:tom 会买哪种车?谁会买 benz?
7
课内实践 23:找朋友,添成语
bell 喜欢运动.
mary 喜欢音乐.
mary 喜欢运动.
jane 喜欢 smith.
smith 喜欢阅读.
john 找朋友的标准是这个人喜欢阅读而且喜欢音乐,或者这个人喜欢运动而且喜欢音乐。 请写出代码让机器找出 john 的朋友。
代码提示: likes(bell,sports). 运行结果: friend(john,Y).
Y = “mary”. 1 Solution
练习2:运行结果
• crosswords(R1,R2,C1,C2,C3) R1 = “大浪淘沙”.
R2 = “席可履厚”.
C1 = “大浪淘沙”.
C2 = “座无虚席”. C3 = “无可厚非”.
R1 = “大浪淘沙”. R2 = “席可履厚”. C1 = “大公无私”. C2 = “座无虚席”. C3 = “无可厚非”.
2 Solutions
9
课内实践 24:推理练习
问题
1、在一条街上,有 3 座房子,喷了 3 种颜色(red,blue,white)。 2、每个房里住着不同国籍的人(english,spanish,dane) 3、每个人养不同的宠物(cat,dog,snails),吃不同的水果 (oranges,pears,apples) 问题是:谁养猫?
线索
1、英国人住红色房子
2、西班牙人养狗
3、蓝色房子紧挨着白房子,在白房子的左边
4、养蛇的人喜欢吃橘子
5、喜欢吃梨的人与养猫的人是邻居
6、住最左边房子的人喜欢吃苹果
7、丹麦人住最右边房子
代码提示
• houses(House1,House2,House3).
%表示出三个房子
• house_info(Colour,Nationality,Pet,Fruit).
• %表示出一个房子应该具备的属性
• one_house(houses(H,_,_),H).
one_house(houses(_,H,_),H).
one_house(houses(_,_,H),H).
• %表示出一个房子可能在的位置
• left_to(houses(H1,H2,_),H1,H2).
left_to(houses(_,H1,H2),H1,H2).
• %表示出二个房子紧挨着并且一个在另一个的左边二种可能的情况
• next_to(Houses,H1,H2) :- left_to(Houses,H1,H2).
next_to(Houses,H1,H2) :- left_to(Houses,H2,H1).
• %表示出二个房子是邻居的规则:H1在H2的左边或者右边
• leftmost(houses(H,_,_),H).
rightmost(houses(_,_,H),H).
• %表示出最左边和最右边房子的位置
表示出线索的部分提示:
clues(Houses) :- one_house(Houses,house_info(red,english,_,_)),
%1、英国人住红色房子 one_house(Houses,house_info(_,spanish,dog,_)),
%2、西班牙人养狗
left_to(Houses,house_info(blue,_,_,_),house_info( white,_,_,_)),
% 3、蓝色房子紧挨着白房子,在白房子的左边
next_to(Houses,house_info(_,_,_,pears),house_info (_,_,cat,_)),
%5、喜欢吃梨的人与养猫的人是邻居
表示出提问的全部代码:
• queries(Houses) :- one_house(Houses,house_info(Colour,Na
tionality,cat,Fruit)). %找出养猫房子的属性
• solve :- clues(Houses), queries(Houses).
• %运行solve,结果是true的话说明有解, 再运行clues(Houses), queries(Houses).即 可看到答案
11
运行效果:
• solve
True
1 Solution
• clues(Houses), queries(Houses).
HOUSES = houses(house_info(“red”,”english”,”cat”,”apples”),house_info(“blue”,”span ish”,”dog”,”pears”),house_info(“white”,”dane”,”snails”,”oranges”)).
1 Solution
推理2 • 问题
• 1、在一条街上,有5座房子,每个房里住 着不同国籍的人(english,dane, norwegian,germen,sweden)
• 线索是:norwegian住在最左边房子,dane 住中间房子,sweden住最右边房子, norwegian和english是邻居, dane和 germen是邻居。
• 问germen住第几间房子?
推理2运行结果
• olve True
1 Solution
clues(Houses), queries(Houses). HOUSES = houses(house_info(“norwegia n”),house_info(“enlish”),house_info(“dane” ),house_info(“germen”),house_info(“swed en”)).
1 Solution
12
推理3 • 问题
• 1、在一条街上,有5座房子,每个房里住着不同 国籍的人(english,dane, norwegian, germen, sweden), 5座房子喷了5种颜色(red,blue, white,yellow,green)
• 线索是:norwegian住在最左边房子,dane住中 间房子,sweden住最右边房子, norwegian和 english是邻居, dane和germen是邻居。黄色房 子与白色房子是相邻的,蓝色房子与绿色房子中 间隔了一个房子,蓝色房子与黄色房子中间也隔 了一个房子, sweden的邻居房子是红色的。
• 问germen住什么颜色的房子?
代码提示:
• left_next(houses(H1,_,H2,_,_),H1,H2). left_next(houses(_,H1,_,H2,_),H1,H2). left_next(houses(_,_,H1,_,H2),H1,H2). next_next(Houses,H1,H2) :-
left_next(Houses,H1,H2). next_next(Houses,H1,H2) :-
left_next(Houses,H2,H1).
推理3运行结果
• solve True
1 Solution
clues(Houses), queries(Houses). HOUSES = houses(house_info(“norwegia n”,”yellow”),house_info(“enlish”,”white”),ho use_info(“dane”,”blue”),house_info(“germe n”,”red”),house_info(“sweden”,”green”)).
1 Solution
13
课内实践 25:爱因斯坦的超级问题
1、在一条街上,有 5 座房子,喷了 5 种颜色(red,green,yellow,white,blue)。 2、每个房里住着不同国籍的人(english,sweden,dane,norwegian,german) 3、每个人喝不同的饮料(coffe,milk,water,tea,beer), 抽不同品牌的香烟(pall_mall,dunhill,blends,prince,blue_master), 养不同的宠物(dog,bird,cat,horse,fish)
问题是:谁养鱼?
线索提示:
1、英国人住红色房子
2、瑞典人养狗
3、丹麦人喝茶 4、绿色房子和白色房子紧邻且在白色房子左面 5、绿色房子主人喝咖啡
6、抽 Pall Mall 香烟的人养鸟 7、黄色房子主人抽 Dunhill 香烟 8、住在中间房子的人喝牛奶
9、 挪威人住第一间房
10、抽 Blends 香烟的人住在养猫的人隔壁 11、养马的人住抽 Dunhill 香烟的人隔壁 12、抽 Blue Master 的人喝啤酒 13、德国人抽 Prince 香烟 14、挪威人住蓝色房子隔壁
15、抽 Blends 香烟的人有一个喝水的邻居
• solve True
运行结果:
1 Solution
clues(Houses), queries(Houses).
HOUSES = houses(house_info(“yellow”,”norweg ian”,”cat”,”water”,”dunhill”),house_info(“blue”,”da ne”,”horse”,”tea”,”blends”),house_info(“red”,”eng lish”,”bird”,”milk”,”pall_mall”),house_info(“green”, “german”,”fish”,”coffe”,”prince”),house_info(“whit e”,”sweden”,”dog”,”beer”,”blue_master”)).
1 Solution
15
课内实践 26:农夫过河
• 有一个农夫带着一头狼、一只山羊和一筐白菜过河,要从南岸过河到北岸。岸边有一条小船,农 夫可以独自划着小船过河,或者每次带其中的一样东西过河。问题是如果他留下狼和羊在一起, 那么狼就会把羊吃掉;如果留下羊和白菜,那么羊就会把白菜吃掉。农夫如何才能安全地将全部 东西运到河对岸?
提示:可以用 farmer、wolf、goat 和 cabbage 分别表示问题中的农夫、狼、山羊和白菜等对象。状态描 述了各个成员的位置,可以用字母 n 和 s 分别表示北岸和南岸,例如,可以用 location(s, n, n, s)表示 农夫、狼、山羊和白菜分别在南岸、北岸、北岸和南岸。动作描述了农夫的摆渡操作,根据题意,一共只 有四种动作,分别是农夫独自划船、农夫带着狼划船、农夫带着山羊划船和农夫带着白菜划船。如何定义 这4个动作?
农夫过河效果截图:
16