本文内容整理自剑桥大学2011-12年David Evans开设的Prolog课程讲义。
Prolog(Programming in Logic)就是暴力美学的代表,一阶逻辑暴搜解决所有问题。
Formulate a “how to compute it” recipe
int sum(int[] list ) {
int result = 0;
for(int i=0; i<list.length; ++i) {
result += list[i];
}
return result;
}
Again formulate a “how to compute it” recipe
(* The sum of the empty list is zero and
the sum of the list with head h and tail
t is h plus the sum of the tail. *)
fun sum([]) = 0
| sum(h::t) = h + sum(t);
% the sum of the empty list is zero
sum([],0).
% the sum of the list with head H and
% tail T is N if the sum of the list T
% is M and N is M + H
sum([H|T],N) :- sum(T,M), N is M+H.
也即陈述式(declarative)的方法
Prolog来源于NLP,现代的Prolog解释器都采用虚拟机
Prolog特点
开源Prolog编译器SWI-Prolog
事实、规则、目标,都用谓词表示
数据有三种类型
1
,3.14
,tigger
X
,A_variable
,_
plus(4,mult(1,9))
(前缀表示法)写法为头部 :- 主体 .
,:-
即为if的意思
rule(X,Y) :- part1(X), part2(X,Y).
rule为真,若part1和part2都为真rule2(X) :- thing(X,Z), thang(Z).
存在Z使得thing和thang都为真注意全称特称量词不显性表达出来
Prolog通过从句(clause)的名字和参数量(arity)来区分,如rule
(rule/0)和rule(A)
(rule/1)指代不同的东西
|
用来代指列表的尾部,如?- [H|T]=[1,2,3,4].
H=1, T=[2,3,4].
first([H|_],H).
last([H],H).
last([_|T],H) :- last(T,H).
len([],0).
len([_|T],N) :- len(T,M), N is M+1.
Prolog里用=
作为测试声明(test assertion),不是赋值,而是验证两者如last([1,2,3],A), A=3.
?- A = 1+2.
A = 1+2.
?- 1+2 = 3.
false.
Prolog的核心只包含非常少的语义,算术操作和其他操作是同级别的,不会得到特别对待
is
算子告诉Prolog
Prolog采用深搜寻找答案
example :- pre, !, post
cut总是成功的,pre的部分随意回溯,但一旦通过!
符号,回溯只能在post进行,而不能再回到!
之前
p(X) :- a(X).
p(X) :- b(X), c(X), !, d(X), e(X).
p(X) :- f(X).
a(1). b(1). c(1). d(2). e(2). f(2).
b(2). c(2).
p(X)
为a(X)
,实例化(instantiate)X=1
满足p(X)
为b(X), c(X), !, d(X), e(X)
(新的目标goal)
X=1
,用事实b(1)
统一b(X)
c(1), !, d(1), e(1)
c(1)
为事实,目标变为!, d(1), e(1)
!
强制执行,前面的条件不能再改变d(1)
,因此failswipl
打开交互界面[user].
创建多行声明;
获取下一个cat test.pl
读文件trace
用来跟踪执行