- A family tree
parent(pam, bob).
parent(tom, bob).
parent(tom, liz).
parent(bob, ann).
parent(bob, pat).
parent(pat, jim).
GNU Prolog 1.4.4 (64 bits)
Compiled Apr 23 2013, 16:05:07 with cl
By Daniel Diaz
Copyright (C) 1999-2013 Daniel Diaz
| ?- consult('C:/Users/Xinqi/Desktop/test.pl').
compiling C:/Users/Xinqi/Desktop/test.pl for byte code...
C:/Users/Xinqi/Desktop/test.pl compiled, 5 lines read - 681 bytes written, 31 ms
(16 ms) yes
% 如果输入的关系符合代码中的关系,那么就输出yes,否则no
| ?- parent(bob, pat).
yes
| ?- parent(liz, pat).
no
| ?- parent(tom, ben).
no
% 这里面,如果其中一个值是大写字母开头,那么就输出满足条件的所有值,即输出liz所有的parent
| ?- parent(X, liz).
X = tom ? ;
(15 ms) no
| ?- parent(X, liz).
X = tom ?
yes
| ?- parent(X, Y).
X = pam
Y = bob ? ;
X = tom
Y = bob ? ;
X = tom
Y = liz ? ;
X = bob
Y = ann ? ;
X = bob
Y = pat ? ;
X = pat
Y = jim
(32 ms) yes
% 这个不难理解,就是输出所有jim的parent,以及jim的parent的parent
| ?- parent(Y, jim), parent(X, Y).
X = bob
Y = pat ? ;
no
| ?-
- 再加入一些rules
parent(pam, bob).
parent(tom, bob).
parent(tom, liz).
parent(bob, ann).
parent(bob, pat).
parent(pat, jim).
female(pam).
male(tom).
male(bob).
female(liz).
female(pat).
female(ann).
male(jim).
在这个基础上,我们也可以加入
sex(pam, feminine).
sex(tom, masculine).
sex(bob, masculine).
mother(pam, bob).
mother(pat, jim).
当然对于mother这一个function,我们也可以直接用prolog定义一下:
% For all X and Y,
% if X is a parent of Y and X is female then
% X is the mother of Y.
mother(X, Y) :-
parent(X, Y),
female(X).
从mother这一function我们可以推出grandparent的function定义:
grandparent(X, Z) :-
parent(X, Y),
parent(Y, Z).
还可以推出sister的关系:
% For all X and Y,
% X is a sister of Y if
% (1) both X and Y have the same parent, and
% (2) X is a female.
sister(X, Y) :-
parent(Z, X),
parent(Z, Y),
female(X).
ATTENTION ATTENTION ATTENTION:
parent(pam, bob).
parent(tom, bob).
parent(tom, liz).
parent(bob, ann).
parent(bob, pat).
parent(pat, jim).
female(pam).
male(tom).
male(bob).
female(liz).
female(pat).
female(ann).
male(jim).
sister(X, Y) :-
parent(Z, X),
parent(Z, Y),
female(X).
如果使用以上的方法编译,在windows10系统上的prolog编译器识别不了male(bob). 之后的function,也就是说,“liz, pat, ann, jim”都会消失不见。
只有将female和male集中在一起写,编译器才能识别。
parent(pam, bob).
parent(tom, bob).
parent(tom, liz).
parent(bob, ann).
parent(bob, pat).
parent(pat, jim).
% 此处需要把female和male分别编写有序排列
female(pam).
female(liz).
female(pat).
female(ann).
male(tom).
male(bob).
male(jim).
sister(X, Y) :-
parent(Z, X),
parent(Z, Y),
female(X).
% 由上述程序可以得出,X不仅仅是ann,还可以是pat,所以pat是她自己的sister
| ?- sister(X, pat).
X = ann ? ;
X = pat ? ;
no
| ?-
所以如何改变这一现状,我们可以加入一个声明
sister(X, Y) :-
parent(Z, X),
parent(Z, Y),
female(X),
X \= Y.
% 加入声明X不等于Y,这样就可以得到确切的值
| ?- sister(X, pat).
X = ann ? ;
no
| ?-
-
如何定义一个ancestor关系
ancestor(X, Z):-
parent(X, Z).
ancestor(X, Z):-
parent(X, Y),
parent(Y, Z).
ancestor(X, Z):-
parent(X, Y1),
parent(Y1, Y2),
parent(Y2, Z).
ancestor(X, Z):-
parent(X, Y1),
parent(Y1, Y2),
parent(Y2, Y3),
parent(Y3, Z).
| ?- ancestor(pam, X).
X = bob ? ;
X = ann ? ;
X = pat ? ;
X = jim ? ;
(31 ms) no
| ?-
-
A robot's world
The robot can only distinguish between a finite number of positions of the objects. The robot can observe the objects with a camera that is mounted on the ceiling. The blocks a, d and e are visible by the camera, whereas blocks b and c are not.
% see(Block, X, Y): Block is observed by camera at coordinates X and Y
see(a, 2, 5).
see(d, 5, 5).
see(e, 5, 2).
% on(Block, Object): Block is standing on Object
on(a, b).
on(b, c).
on(c, table).
on(d, table).
on(e, table).
% Note the underscore character in the question.
% The underscore indicates an 'anonymous' variable.
% It stands for anything, and we are not interested in its value.
| ?- on(Block, _).
Block = a ? ;
Block = b ? ;
Block = c ? ;
Block = d ? ;
Block = e
(47 ms) yes
| ?- see(B1, _, Y), see(B2, _, Y). % B1 and B2 both seen at the same Y
B1 = a
B2 = a
Y = 5 ? ;
B1 = a
B2 = d
Y = 5 ? ;
B1 = d
B2 = a
Y = 5 ? ;
B1 = d
B2 = d
Y = 5 ? ;
B1 = e
B2 = e
Y = 2
(31 ms) yes
| ?- see(B1, _, Y), see(B2, _, Y), B1 \= B2. % B1 and B2 not equal
B1 = a
B2 = d
Y = 5 ? ;
B1 = d
B2 = a
Y = 5 ? ;
(16 ms) no
| ?- on(B, _), % B is on something, so B is a block
on(_, B). %Something is on B, so B is not visible
B = b ? ;
B = c ? ;
(31 ms) no
% '\+' is Prolog's negation of see(B, _, _).
| ?- on(B, _), % B is on something, so B is a block
\+ see(B, _, _). % B is not seen by the camera
B = b ? ;
B = c ? ;
no
| ?-