1.6 逻辑式编程

逻辑式编程(Logic Programming)是一种面向演绎推理的逻辑型程序设计语言,其中约束满足问题(Constraint Satisfaction Problem, CSP)是变量集合和约束条件的集合,问题领域甚至可以一直扩展到人工智能级别。

Prolog语言使用了一个深度优先搜索的决策树,它使用所有可能组合与规则集合相匹配,且编译器对这个过程做了很好的优化。不过,这个策略需要进行大量计算,尤其是数据规模非常大的时候。以下通过一个Prolog的简单示例给大家展示逻辑式编程的一隅,如代码清单1-5所示。

代码清单1-5 Prolog简单示例


// 输入- 事实
car(civic).
car(malibu).
japanese(civic).
american(malibu).
owns(john, malibu). owns(john, civic).
owns(fred, civic). owns(joe, malibu).

// 输入- 规则
vehicle(X) :- car(X).
gets_good_gas_millage(X) :- owns(X, civic).

// 输入- 目标1 John和Fred都拥有的车子是什么? 2 谁拥有日本车?
?- owns(john, Car), owns(fred, Car).
?- owns(Person, Car), japanese(Car)

// 返回- 结果
?- owns(john Car), owns(fred, Car).
Car = civic.

?- owns(Person, Car), japanese(Car).
Person = john,
Car = civic ;
Person = fred,
Car civic ;

像做数学题一样,我们给出公理(事实)、已知条件(规则)、问题(查询),然后等待编译器给出结果。

编译器给出的结果并不一定是唯一的,但它一定是正确的。我们不必关心系统/编译器给出结果的过程,比如早期联网系统(文字界面)都是直接返回交互式信息检索和分析的结果,或是我们希望通过Math库得到一个满足条件的随机数。这类情况都是只需要获得结果,不需要细究过程。

在前端,我们也会不断进行一些黑盒封装,或在使用工具时将工具当作黑盒处理,选择相信工具中的编码实现是高效和准确的。比如在我们使用的前端框架(Vue/React)中,样式数据变化会自动触发组件更新,编码者对于组件的更新机制是信任的,这一行为也是逻辑式编程思想的体现。