逻辑编程与函数编程的介绍

逻辑编程(又称关系范式)的突出优势是什么?因为该死的美学,逻辑编程简直太美了,他们自然的声明胜过于函数式编程中的任何宝石。逻辑编程使用搜索,这样能够就不会被算法细节牵着鼻子走,如果你还没有尝试过Prolog,关系编程简直无法让人想象。

学习关系范式最重要原因是因为它有趣。

swannodette/logic-tutorial提供了在Clojure 下学习逻辑编程的开源项目。

准备:
键入lein repl或cake repl
进入Cojure提示界面,输入:
user=> (require 'clojure.core.logic)
user=> (load "logic_tutorial/tut1")
user=> (in-ns 'logic-tutorial.tut1)
这样就准备好了环境。

关系编程是问计算机问题,在问问题之前,我们需要计算机了解一些事实,比如男人。
tut1=> (defrel man x)
#'tut1/man
然后定义几个不同名字的人:
tut1=> (fact man 'Bob)
nil
tut1=> (fact man 'John)
nil
然后我们就可以提问男人是谁?问问题使用run,希望计算机将可能的答案给q:
tut1=> (run 1 [q] (man q))
(John)

我们刚才问了只有一个答案的问题,可以问超多个答案的问题:
tut1=> (run 2 [q] (man q))
(John Bob)

如果问更多呢?
tut1=> (run 3 [q] (man q))
(John Bob)

同样回答。这是因为我们已经告诉计算机这个世界上有两个男人,它不能给我们它不知道的。

下面让我们定义另外一种关系和事实:
tut1=> (defrel fun x)
#'tut1/fun
tut1=> (fact fun 'Bob)
nil
问一个新问题:
tut1=> (run* [q] (man q) (fun q))
(Bob)
我们使用run*,这意味着所有这个问题的答案都会出现,问题是:谁是男人而且有趣。

再定义新的:
tut1=> (defrel woman x)
#'tut1/woman
tut1=> (fact woman 'Lucy)
nil
tut1=> (fact woman 'Mary)
nil
tut1=> (defrel likes x y)
#'tut1/likes

关系不一定有关单个实体,可以在事情之间定义关系:
tut1=> (fact likes 'Bob 'Mary)
nil
tut1=> (fact likes 'John 'Lucy)
nil
tut1=> (run* [q] (likes 'Bob q))
(Mary)
我们可以问谁喜欢谁这样的关系问题。

tut1=> (run* [q] (likes 'Mary q))
()
却没有答案,因为我们没有说过Mary被谁喜欢,只有“Bob喜欢Mary”。

看看:
tut1=> (fact likes 'Mary 'Bob)
nil
tut1=> (run* [q] (fresh [x y] (likes x y) (== q [x y])))
([Mary Bob] [Bob Mary] [John Lucy])

这里fresh是 Clojure vector类似数组,存放谁喜欢谁很多可能值。

再看看:
tut1=> (run* [q] (fresh [x y] (likes x y) (likes y x) (== q [x y])))
([Mary Bob] [Bob Mary])
只列出谁彼此喜欢的人。

完,有兴趣者可进入项目主页继续学习研究。


逻辑比起函数更抽象,函数式被接受的时候,逻辑式才有得崛起(连函数都接受不了,逻辑怎么办)。这大多是历史问题,因为教学是教我们写程序,而不是写软件。

高阶函数到逻辑式

我有一种直觉,逻辑编程谈的逻辑可能不是我们讲的复杂业务逻辑的逻辑。

函数编程典型图如下:

10 --> +5 ---> 15

10被输入,通过+5计算,得出15输出结果。

当我们面向计算机这个强势动物时,我们崇拜它,向它询问,把条件输入,得到它函数处理的结果。

但是,如果我们面向复杂业务这个强势动物时,我们也得崇拜它啊,那这个两个强势动物放在一起如何让我们崇拜谁呢?

10是一种输入,但是10本身代表复杂业务,不是一个数字10这么简单,我们就无法将它送到函数机器中处理。

复杂业务可能变成是:

(10 +5) -->15

10代表业务领域模型,它将算法(+5)涵括在其中,而不是它自己被送到算法(+5)里面处理。

这大概是面向业务逻辑和面向函数逻辑的区别吧。逻辑编程大概只是面向函数逻辑的一个升级版而已。


2013-11-19 09:39 "@banq"的内容
逻辑编程大概只是面向函数逻辑的一个升级版而已。

Prolog是用一阶谓词逻辑系统,而函数是lambda演算逻辑系统。这两者之间不是什么升级版关系。


2013-11-20 08:47 "@
SpeedVan"的内容
Prolog是用一阶谓词逻辑系统,而函数是lambda演算逻辑系统。这两者之间不是什么升级版关系。 ...

@banq

一阶谓词逻辑与lambda
[该贴被SpeedVan于2013-11-25 17:24修改过]

多谢,看了一下,不明觉厉。
对自然语言的破解是总体方向,不过现在机器学习提供了新的方向,通过大数据训练,模拟人的认知方式,这条路获得了突破。反过来说明以前的方向走入了死胡同。