练习题5.1
Prolog会如何回答下面的问题?
1. X = 3*4.
2. X is 3*4.
3. 4 is X.
4. X = Y.
5. 3 is 1+2.
6. 3 is +(1,2).
7. 3 is X+2.
8. X is 1+2.
9. 1+2 is 1+2.
10. is(X, +(1,2)).
11. 3+2 = +(3,2).
12. *(7,5) = 7*5.
13. *(7, +(3,2)) = 7*(3+2).
14. *(7, (3+2)) = 7*(3+2).
15. 7*3+2 = *(7, +(3,2)).
16. *(7, (3+2)) = 7*(+(3,2)).
我的答案和解释:
1. Prolog会回答:X = 3*4,因为这是一个合一。
2. Prolog回答: X = 12,因为is会促使计算。
3. Prolog会报错,因为变量X出现在is右端,没有初始化。
4. Prolog会回答:X = Y. 因为这是一个合一,变量X和Y会共享一个值。
5. Prolog会回答:true。
6. Prolog会回答:true。
7. Prolog会报错,因为变量X出现在is右端,没有初始化。
8. Prolog会回答:X = 3。
9. Prolog会回答:true。
10. Prolog会回答:X = 3。
11. Prolog会回答:true。
12. Prolog会回答:true。
13. Prolog会回答:true。因为两个复杂语句能够合一。
14. Prolog会回答:true。因为两个复杂语句能够合一。
15. Prolog会回答:false,因为两个复杂语句不能合一,第一个复杂语句为:7*3+2,第二个复杂语句为:7*(3+2)。
16, Prolog会回答:true,因为两个复杂语句能够合一。
练习题5.2
1. 定义一个谓词increment/2,其中第二个参数比第一个参数大1,比如,increment(4, 5)是正确的,increment(4,6)是错误的。
2. 定义一个谓词sum/3,其中第三个参数是第一个参数和第二个参数之和,比如sum(4, 5, 9)是正确的,sum(4, 6, 12)是错误的。
我的答案:
1. increment(First, Second) :- Second is First + 1.
2. sum(Add1, Add2, Sum) :- Sum is Add1 + Add2.
练习题5.3
定义一个谓词addone/2,其中第一个参数是整数列表,第二个参数是第一个整数列表每个对应位置元素加1后的整数列表,比如,查询:
?- addone([1, 2, 7, 2], X).
X = [2, 3, 8, 3]
我的答案:
addone([], []).
addone([H1|T1], [H2|T2]) :- H2 is H1 + 1, addone(T1, T2).
练习题5.4
在之前的章节里,我们已经讨论了accMax/3谓词,可以返回一个整数列表的最大值。请稍微修改这个谓词,转换为另外一个谓词,accMin/3,可以返回一个整数列表的最小值。
我的答案:
accMin([H|T], A, Min) :- H < A, accMin(T, H, Min).
accMin([H|T], A, Min) :- H >= A, accMin(T, A, Min).
accMin([], A, A).
min([H|T], Min) :- accMin([H|T], H, Min).
练习题5.5
在数学中,一个n阶向量是n个数字组成的列表。比如,[2, 5, 12]是一个3阶向量,[45, 27, 3, -4, 6]是一个5阶向量。关于向量一个基础的操作时标量乘法,在这个操作中,向量中的
每个元素都和一个数字相乘。比如,如果将一个3阶的向量[2, 7 ,4]和数字3进行标量乘法,得到了结果是一个3阶向量:[6, 21, 12]。
请写出一个谓词scalarMult/3,其中第一个参数是一个整数,第二个参数是一个整数列表,第三个参数是标量乘法的结果,比如:
?- scalarMult(3, [2, 7, 4], Result).
Result = [6, 21, 12]
我的答案:
scalarMult(Num, [], []).
scalarMult(Num, [H|T1], [H1|T2]) :- H1 is H*Num, scalarMult(Num, T1, T2).
练习题5.6
接上题,在向量中另外一个基础操作时点乘(dot product)。这个操作将会合并两个相同阶的向量为一个数字。具体操作方式是:两个向量相同位置的元素相乘,然后将结果相加。比如,
[2, 5, 6]和[3, 4, 1]的点乘是:6 + 20 + 6,即32。请写一个dot/3,第一个参数是一个整数列表,第二个参数是和第一个参数长度相同的整数列表,第三个参数是点乘的结果。比如:
?- dot([2, 5, 6], [3, 4, 1], Result).
Result = 32
我的答案:
dotAcc([], [], Acc, Acc).
dotAcc([H1|T1], [H2|T2], Acc, Result) :-
NewAcc is Acc + (H1*H2),
dotAcc(T1, T2, NewAcc, Result).
dot(L1, L2, Result) :- dotAcc(L1, L2, 0, Result).