本文内容整理自剑桥大学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,tiggerX,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用来跟踪执行