用Prolog优雅地解决一个逻辑谜题

2025-04-08
用Prolog优雅地解决一个逻辑谜题

作者用Prolog语言重写了其编程逻辑书籍中关于逻辑编程语言的章节,并以一个“Layton谜题”为例展示了Prolog的强大功能。该谜题需要根据前三个学生的成绩推断第四个学生的成绩。作者通过简洁的Prolog代码(仅15行),巧妙地利用了Prolog的模式匹配和双向性,优雅地解决了该问题,并找到了所有可能的答案键,最终得出第四个学生的成绩为6分。作者对比了其代码与他人代码的长度,并指出其代码更简洁高效。尽管作者认为谜题不适合用于教学,但他仍然以该例子展示了Prolog的实际应用潜力。

阅读更多
开发 谜题求解

是时候停止构建 KV 数据库了

2025-03-25
是时候停止构建 KV 数据库了

作者痛斥 Key-Value 数据库过于简单,缺乏表达能力,使用起来十分痛苦。虽然 KV 数据库在存储引擎供应商中很流行,但其本质只是一个构建合理数据模型的基石,使用者需要从头构建数据模型,且效果往往不佳。作者提倡一种介于关系型数据库和 KV 数据库之间的方案:具有类型化记录的嵌入式数据库,逻辑和物理模式分离,但查询针对物理模式编写,避免了复杂的查询规划器,并支持异步模式更改和布局切换。这种方案在兼顾数据独立性的同时,避免了关系型数据库的复杂性,更适合嵌入式场景。

阅读更多
开发

验证优先开发:超越测试驱动开发的新范式

2025-03-18
验证优先开发:超越测试驱动开发的新范式

本文探讨了“验证优先开发”(VFD)的概念,它强调在编写代码之前先建立验证机制,例如编写测试、定义类型不变式或添加契约等。VFD 与测试驱动开发(TDD)不同,TDD 是 VFD 的一种特例,更强调测试驱动代码设计。VFD 的优势在于降低跳过验证的可能性,尽早发现错误,并提高代码质量。但 VFD 也存在缺点,例如会减慢开发速度,妨碍探索式编程,以及验证方法可能影响代码设计。作者认为 VFD 作为一种技术,而非范式,更灵活且易于与其他方法结合使用。

阅读更多
开发 验证优先

五种非确定性:形式化方法的实用见解

2025-02-20
五种非确定性:形式化方法的实用见解

本文探讨了系统建模中五种非确定性的类型:真随机性、并发性、用户输入、外部因素和抽象。作者以通俗易懂的方式解释了每种类型的特点,并结合实际案例进行说明。例如,真随机性虽然可以使用伪随机数生成器模拟,但在建模时通常被视为非确定性选择;并发性是导致非确定性的主要来源之一,其状态空间爆炸问题需要特殊处理;用户输入和外部因素都可被视为非确定性的外部影响。最重要的是,抽象可以将复杂的确定性过程简化为非确定性选择,从而简化模型并提高其对潜在错误的敏感性。这篇文章为理解非确定性及其在软件开发中的应用提供了宝贵的参考。

阅读更多
开发

效率与横向扩展:鱼与熊掌能否兼得?

2025-02-12
效率与横向扩展:鱼与熊掌能否兼得?

本文探讨了软件效率和横向扩展之间的矛盾。作者指出,为扩展性优化的软件通常在单机环境下效率较低,反之亦然。这源于Amdahl定律、协调开销以及共享资源的限制。高效的算法往往依赖于对系统和问题的特定假设,而这些假设在横向扩展后可能不再成立。作者还探讨了文化因素和任务类型对选择的影响,并以Tigerbeetle数据库和CPython的GIL为例进行说明,最终指出,对问题和环境的深入理解是提升效率和扩展性的关键。

阅读更多
开发

正则表达式中`$`和`^`作为行锚点的历史渊源

2025-01-21
正则表达式中`$`和`^`作为行锚点的历史渊源

本文探讨了正则表达式中使用`$`和`^`作为行锚点的历史原因。追溯到QED文本编辑器,`$`最初在QED中表示缓冲区的末尾,Ken Thompson将其改编为正则表达式中的行尾锚点。而`^`的选择,则可能因为在当时常用的Teletype Model 35打字机上缺乏其他合适的符号,且`^`在ASCII-67中已存在。这一选择并非巧妙的设计,而是受限于当时的硬件和字符集的限制,最终成为正则表达式的约定俗成。

阅读更多
开发 QED

数学建模揭示:旋转陀螺游戏Dreidel有多糟糕

2024-12-18
数学建模揭示:旋转陀螺游戏Dreidel有多糟糕

博主去年使用PRISM概率建模语言对传统节日游戏Dreidel进行了建模,证明其缺乏乐趣。今年,他完善了模型,使其能够模拟直至游戏结束的全过程。新的模型修正了之前仅模拟首位玩家出局的缺陷,并改进了计算押注和玩家出局逻辑。通过模型模拟,博主发现,平均而言,一场四名玩家的游戏需要760次旋转才能结束,最长甚至可能超过6小时。这充分证明了Dreidel游戏冗长乏味,令人沮丧。

阅读更多

关于DuckDB疯狂语法特性的思考

2024-12-03
关于DuckDB疯狂语法特性的思考

本文探讨了DuckDB允许用户通过扩展在运行时修改SQL语法这一特性。作者认为,对于一次性分析查询而言,这种语法扩展能力非常有吸引力。文章进一步探讨了通过解析表达式语法(PEG)实现这一特性的可能性,并提出了一个更深层次的想法:将语言按功能分解,每个功能都包含其语法和语义解析。作者还实现了一个简单的原型,演示了如何动态添加数组字面量到语言中,并讨论了这种方法的优缺点以及未来研究方向。

阅读更多
未分类 语法扩展

我算是服了!来玩玩跳表吧

2024-12-01
我算是服了!来玩玩跳表吧

本文探讨了LSM树及其核心组件memtable的实现方式。作者认为无锁并发跳表是memtable的最佳选择,尽管其较为复杂。文章详细解释了memtable的需求:快速读写、并发读写支持、有序扫描以及内存限制。作者研究了跳表的并发写操作,比较了单写多读和多写多读的实现,并通过模拟实验探究了概率p和最大高度对跳表性能的影响。

阅读更多
未分类 LSM树 memtable

文档的缺失会导致迷信

2024-11-30
文档的缺失会导致迷信

作者分享了在使用OneNote的“墨迹转形状”功能时遇到的困惑。由于缺乏文档说明,作者只能通过反复尝试来理解该功能的运作方式,并对某些操作产生了类似“迷信”的想法,就像斯金纳的鸽子实验一样。作者呼吁软件开发者提供更完善的文档,避免用户因缺乏指导而产生不必要的猜测和误解。

阅读更多
未分类 OneNote 迷信

五个不寻常的Raku语言特性

2024-11-13
五个不寻常的Raku语言特性

本文介绍了Raku编程语言的五个独特之处:Junctions(用于布尔逻辑的复合值)、Whatevers(多功能占位符,可用于创建匿名函数)、正则表达式(改进的可组合性和语法)、Hyperoperators(用于并行列表操作的特殊运算符)以及Pair语法(用于简洁定义键值对的语法糖)。文章还简要提及了Slangs(语法扩展)和RakuAST(抽象语法树处理),并推荐了一些Raku相关的博客和资源。

阅读更多
未分类 语法特性

概率冒险之旅

2024-11-11
概率冒险之旅

作者反思了学生时代对统计学学习的遗憾,并分享了近期对概率和统计学的深入学习。文章重点介绍了指数分布在排队论、控制论和性能建模中的普遍性,并以CoDel算法为例,解释了如何模拟排队系统。作者通过模拟泊松点过程,阐述了指数分布的无记忆性以及如何利用该特性简化模拟过程。最后,作者反思了指数分布的教学方法,认为应该先介绍无记忆性的概念和优势,再引出指数分布这一唯一具备该特性的连续分布。

阅读更多
未分类 指数分布

将设计与工程分离

2024-10-31
将设计与工程分离

本文探讨了在小型工程团队中,如何在没有专职设计师的情况下交付美观、直观的软件。作者提倡将设计工作与工程工作分离,即先进行纯粹的设计,再进行工程实现。作者认为,工程师在编码时容易受限于现有代码和技术能力,导致设计缺乏创造性。而将设计与工程分离,可以让工程师跳出思维定式,设计出更优秀的产品。作者还分享了具体的实践方法,例如离开工作站、寻找新的环境、手绘设计稿等。

阅读更多
未分类

TLA+入门:从基本原理出发

2024-10-25
TLA+入门:从基本原理出发

本文介绍了TLA+的基础数学原理,以及如何用其进行系统建模。文章以银行账户转账为例,逐步讲解如何使用谓词逻辑、时间变量、状态转换等概念描述系统行为。并引入了时间逻辑、Stutter步骤、不变式等关键概念,最终用TLA+语言表达了转账模型和无透支属性。文章还讨论了如何简化模型以提高可验证性,并鼓励读者思考如何扩展模型以支持双向转账。

阅读更多
未分类 系统建模