dram.me

脱字符表示法

PicoLisp对于字符串中包含特殊字符的表达模式有些特别。在C语言中,转意字符是有直接含义的,比如\n是newline的缩写,\t是tab的缩写。但PicoLisp中用到的字母是什么含义呢?这其实是脱字符表示法。

脱字符表示法通过^以及随后的连续可显示字符@ABC等表示ASCII值为0123的不可显示字符,详细的介绍可以查看维基百科的说明。

另外,严格来说^不能说是脱字符,脱字符位于下方。^称作抑扬符,详细的说明见维基百科

是什么和为什么

在《交互式培训》中,作者认为知识可以分为“陈述性知识”和“程序性知识”两类。由此想到“是什么”和“为什么”这两者的关系。“是什么”是陈述式的,但“为什么”因为牵扯到推导的过程,所以很多时候是程序式的。

对一个知识点,只有同时包含“是什么”和“为舌么”这两部分,对此的理解才是足够深刻的。所以在培训或学习时,需要同时关注“陈述式”和“程序式”的方法。

miniKanren学习

基于在Scheme中实现Prolog的讨论,开始学习miniKanren,虽然miniKanren的资料非常丰富,但入门的门槛依然有点高。可能是以下原因:

入门材料

以下是我整理的入门材料(前提是具备Scheme和Prolog基础):

陷阱

几个容易踩的坑:

  • 论文中的exist已经被替换为fresh,具体原因还有待研究;

  • 论文中通过文字排版简化了quote,在转化为代码时需要重新加上,可以参考交互教程;

  • run的结果(_.0)并非pair类型的(_ . 0),而是单元素_.0的列表。

在Scheme中实现Prolog

补遗

  1. 还可以参考PicoLisp与数据库和查询相关的设计与实现。—— 2017-03-12

  2. 可以参考Racket的Datalog和Common Lisp的多个Prolog实现。另外Racket的Racklog作为Schelog的移植版本,也可以参考。—— 2017-03-13

  3. Prolog和Scheme的一点区别是:对于非专业人士或者初学者来说,Prolog更易于猜测和理解。如果需要在设计中引入编程语言表达严谨的复杂逻辑,可读性和易于理解都非常重要。—— 2017-03-17

在对LogtalkProlog模块的讨论中,暴露出Prolog模块存在的一些问题,特别是模块名称冲突问题,在当前的生态环境下,并没有好的解决方案。

另一方面,Prolog过渡依赖于运算符的语法模式在一定程度上影响了初学者对代码的理解。还有逻辑和控制部分的耦合也并不十分理想。

基于以上的原因,考虑是否能够在Scheme中实现类似Prolog中数据表示和搜索的机制。正如George F. Luger在《人工智能》中所说的,这是AI最为基本的两个功能,以此作为对Scheme的补充。

以下是零碎的想法,想在研究miniKanrenSchelog之前记录下来。

Logtalk中的模块机制

补遗

  1. 这里对Prolog模块的理解不对,模块名是全局的,在SWI和Yap中,都不允许模块名冲突,即使属于不同目录。—— 2017-03-11

Logtalk中并没有模块机制,而是完全依赖对象进行封装和名字空间隔离。

对象直接的依赖采用加载器处理。但这存在一个问题,当出现对象名称冲突时,这个机制无法解决。例如两个lgt文件中同时定义了foo对象,在单个程序中就无法同时使用这两个库。

Prolog主流的模块系统虽然也可能出现名称冲突的问题(包括模块名冲突和谓词名冲突),但可以通过辅助模块包装规避。例如模块a和模块b同时定义了谓词foo,可以定义辅助模块c,封装a中的foo,之后模块b即使不使用模块名前缀机制,也可以间接使用a中的foo了。如果出现模块名冲突,也可以用类似的思路处理。

由于Logtalk中所有对象名都是全局名字,不能像Prolog的名字那样在模块内局部化,所以无法使用类似的机制。

← older posts