逻辑编程相关技术研究与进展
1 SLG - WAM中的增量答案完成
1.1 复杂度分析
对于不需要答案完成(ANSWER COMPLETION)的程序查询,可以在 $O(size(P))$ 时间内完成评估。这类程序包括分层程序,以及动态依赖图中负强连通分量(SCC)内无正循环的非分层程序。
定理1:设 $Q$ 是对有限基正规程序 $P$ 的查询。在对每次评估中每个SLG森林的所有子目标、节点和延迟元素进行常量时间访问,以及对 $P$ 中的每个子句进行常量时间访问的成本模型下,可以构建一个不执行答案完成的部分SLG评估,其时间复杂度与 $P$ 的大小呈线性关系。
ITERATE ANSWER COMPLETION算法会迭代应用答案完成操作,并调用Check Supported Answers() 检查正循环。Check Supported Answers() 是Tarjan的SCC检测算法的一种改编,其时间复杂度与 $size(P)$ 呈线性关系。
在最坏情况下,需要迭代应用答案完成操作,每次应用时会发现一个原子为假。此时,程序评估的成本与 $atoms(P) × size(P)$ 成正比,这与已知的良基语义(WFS)复杂度相当。
1.2 答案完成的实现
在SLG评估中,表列子目标可以标记为已完成,这意味着该子目标的所有可能答案都已生成,但可能仍需进行简化和答案完成操作以简化或删除条件答案。已完成的子目标不需要执行栈空间,只需要表空间,因此尽早完成子目标对引擎效率至关重要。
SLG - WAM通过完成指令执行增量完成,该指令维护相互依赖的子目标集(SCC)的信息,并在所有适用操作执行完毕后完成每个SCC。除了将SCC中的每个子目标 $S$ 标记为已完成外,如果 $S$ 失败(无答案),完成指令可能会对负依赖于 $S$ 的条件答案发起简化操作。
在答案完成方面,条件答案的延迟文字中的任何正循环都必须包含在正在完成的SCC内,因为每个延迟文字在延迟之前都是一个选定文字。这种增量方法有以下好处:
- 在完成指令内执行答案完成操作可限制此类操作的搜索空间。
- 在SCC内的所有其他简化操作完成后执行答案完成同样可减少搜索空间。
- 若SCC内未执行延迟操作,则不需要进行答案完成,这一事实可通过SLG - WAM的完成栈中的数据结构轻松维护。
以下是Iterate Answer Completion() 的伪代码:
Algorithm Iterate Answer Completion(CompletionStack)
reached fixed point = FALSE;
while not reached fixed point
reached fixed point = TRUE;
foreach subgoal S in the Completion Stack
foreach answer A for subgoal S
if not Check Supported Answer(A)
/* A is unsupported */
reached fixed point = FALSE;
delete A;
propagate A’s deletion’s simplifications;
Check Supported Answer过程用于实际检查一个(正)答案是否无支持。当遇到已访问且在SCC内的答案时,它会检测到正循环,此时算法返回FALSE表示答案无支持;若答案已访问但不在SCC内,则表示该答案是在查询求解的其他分支中生成的,算法返回TRUE。检查未访问答案的步骤如下:
1. 将其标记为已访问。
2. 将其添加到搜索状态(存储在完成栈中)。
3. 遍历答案的延迟列表中的所有延迟元素,递归检查每个元素的支持性。
当确定一个答案无支持时,会删除包含该答案的所有延迟列表,这可能会导致进一步的简化和答案完成迭代。
以下是Check Supported Answer的伪代码:
Algorithm Check Supported Answer(Answer)
if Answer has already been visited
if Answer is in the SupportCheckStack return FALSE;
else return TRUE;
else
mark Answer as visited;
push Answer onto the SupportCheckStack;
mark Answer as supported unknown;
foreach Delay List DL for Answer
if Answer is supported true exit loop;
mark DL as supported true;
foreach Delay Element DE in the Delay List DL
if DL is not supported true exit loop;
if DE is positive and it is in the SupportCheckStack
recursively call Check Supported Answer(Answer of DE)
if Answer of DE is not supported true
mark DL as supported false;
if DL is supported false
remove DL from Answer’s DLs list
if Answer’s DLs list is now empty
delete Answer node;
simplify away unsupported positives of Answer;
else mark Answer as supported true;
if the Answer node was deleted return TRUE;
else return FALSE;
这个算法已在XSB的完成指令中实现,全面的性能分析仍在进行中。初步结果显示了该启发式方法的优势:像win/1这样的传统基准测试要么不使用简化操作,要么很少使用,因此答案完成没有额外开销。对示例1进行大量重复的压力测试显示,额外开销最多为18%。示例1代表了需要答案完成的典型情况,因为它包含(至少)两个关于某个文字(如 $p(X)$ )的规则,第一个规则依赖于通过否定的循环(使 $p(X)$ 未定义),第二个规则依赖于无支持的正循环。只有答案完成可以清除第二个规则答案中包含 $p(X)$ 的延迟列表。
1.3 结论
WFS在越来越多的应用中得到使用,从智能代理到对象逻辑中的继承,再到供应链分析。然而,将WFS嵌入到像Prolog这样的编程语言的语义核心时,其抽象复杂度是一个问题。定理1表明,WFS的非线性可以与WFS引擎的其他部分分离;这里提出的算法优化以及初步性能结果,凸显了WFS适用于通用编程。
2 事务逻辑程序的表列评估
2.1 引言
事务逻辑(TR)是经典逻辑编程的扩展,支持可回溯的状态更新,它有一个类似于Prolog的SLD推导的自顶向下评估算法,但扩展了状态的执行路径,而不是单一的全局状态。这种反向链算法可能效率低下,因为它会多次重新计算相同的事务查询,或者在计算递归程序的答案时可能会陷入无限循环,无限次访问相同的状态路径。
为了解决这些问题,对于顺序事务逻辑,通过将调用、调用初始状态、合一(答案)和返回状态存储在可搜索结构中进行记忆化(缓存);对于并发事务逻辑,为查询构建图并对准备当前执行的节点进行表列。事务逻辑表列的重要问题包括状态的存储、索引、更新、查询和恢复。在XSB Prolog中实现并测量了用于表列具有可回溯更新的程序的多种数据结构的效率。研究了这些数据结构及其在TR的各种应用中的性能,如人工智能规划、NP完全图算法(哈密顿循环、团、最短消耗路径、连通分量)和主动数据库。一种很有前途的技术是将日志(即相对于物化状态的插入和删除)存储在单独的字典树(为查询进行了优化)中,同时保留一个全局页面字典树作为重启的公共索引。
2.2 事务逻辑的表列
逻辑编程表列在处理列表和其他结构化术语时效率低下。大多数情况下,这些复杂术语是非区分性参数或不用于表列的术语,例如以列表表示的大状态和累积结果。一个直观而简单的解决方案是使用程序数据库存储这些大参数,并使用可回溯更新来更改它们。
TR是专门为基于规则的范式设计的通用逻辑,旨在为状态更改操作提供声明性解释。基本的可回溯转换 $ins/1$ 和 $del/1$ 指定了数据库当前状态的基本更新,由一个神谕执行,该神谕通过在扩展数据库中插入或删除一个原子将数据库带入新状态。
复杂公式由原子公式和基本转换使用连接词和量词构建(与逻辑编程中的类似,但有并发合取运算符 “|” 除外)。TR公式的真值是在路径上确定的,路径是有限的状态序列。如果公式 $\pi$ 可以从状态 $s_1$ 开始执行,将数据库更改为状态 $s_2, s_3, …$ 并最终在状态 $s_n$ 终止,则公式 $\pi$ 在路径 $ $ 上为真。
逻辑编程的表列技术是为了重用等效查询(变体或包含等价)的所有调用的计算分支。对于事务逻辑的表列,将调用和答案合一与其初始和返回状态配对。每当发出对表列谓词的新调用时,都会查询这个调用 - 答案表。如果在初始数据库状态下发出的调用与在相同初始状态下的表列调用相似,则可以使用答案集和返回状态来满足该调用。如果调用表中没有该调用的条目,则将其插入表中,并使用类似SLD的解析对程序子句进行解析。在这个过程中推导出每个答案后,将其插入与该调用关联的表条目。答案添加到集合后,会安排将其返回给查找表中存储的所有等效先前调用。如果未找到答案,则评估失败并回溯执行。
事务逻辑表列的常见问题包括:
- 查询当前状态中的事实。
- 检查当前状态是否之前遇到过,然后进行插入操作。
- 通过使用答案表中的返回状态更改当前状态来恢复挂起的调用。
- 表列日志与物化状态的比较以及优化。
实现并测量了用于存储状态的各种数据结构的性能:从有序列表表示的状态、存储在带有显式状态标识符的字典树上的物化状态、使用哈希增量函数索引状态,到作为字典树的日志和全局状态字典树。
对TR在规划和哈密顿路径应用中的实验表明,系统性能从以列表存储状态时的不可行,发展到以字典树表示日志时的几秒内完成。空间仍然是一个非常重要的问题,因为字典树不是状态集的最优表示。选择性物化可能会增加共享,但会对计算造成很大负担(例如,检查状态 $ $ 是否存在于之前见过的状态池中,需要物化并比较多个状态,时间复杂度与状态大小呈线性关系)。
TR表列技术可以扩展到并发事务逻辑程序的表列,通过为程序和查询构建图,并记忆化 “热点” 顶点(例如,可能执行的顶点)。目前仅针对命题逻辑程序开发了该技术,还需将其扩展到谓词情况。
2.3 流程总结
以下是事务逻辑表列评估的主要流程:
graph TD;
A[开始查询] --> B{调用是否在表中};
B -- 是 --> C[使用表中答案和返回状态];
B -- 否 --> D[插入调用到表中];
D --> E[使用SLD解析程序子句];
E --> F[推导答案];
F --> G[插入答案到表中];
G --> H[返回答案给等效先前调用];
C --> I{是否还有查询};
H --> I;
I -- 是 --> A;
I -- 否 --> J[结束];
3 大规模分布式系统的逻辑编程
3.1 引言和问题描述
研究旨在寻找一种更好的方法来对大规模分布式系统进行编程。随着这类系统的需求日益增加,编程变得至关重要。然而,现代语言中现有的并发模型对于程序员来说很难理解和推理。许多程序员在编写和调试并发程序时面临极大困难,更不用说大规模分布式程序了。竞态条件尤其难以发现、理解和解决。
目前在Claytronics系统的背景下研究这个问题,Claytronics是一个旨在创建可编程材料的模块化机器人系统。这些机器人形成集合,即网络可变的大规模分布式系统,具有移动节点和现实世界不确定性的额外复杂性。这些集合预计最终将包含数百万个节点。
3.2 背景和现有文献概述
近年来,伯克利有一些关于将逻辑编程用于分布式系统的工作。特别是,P2和SNLog分别使用逻辑编程方法处理覆盖网络和传感器网络。这些系统没有设计用于处理集合中频繁的网络拓扑变化,并且缺乏证明其程序正确性所需的形式语义。其他非逻辑编程的方法也存在类似的缺点。
3.3 研究现状
通过开发围绕并发设计的新编程语言和范式来探索替代编程模型。创建了一种类似Datalog的编程语言Meld,用于在集合上运行。Meld基于这样的理念:程序员应将集合作为一个整体进行编程,无需担心实现细节,如程序的各个部分应在何处执行,或节点之间需要发送什么消息。相反,程序员专注于程序的逻辑,将其表示为一组根据当前状态更改集合状态的规则。
程序员可以隐式指定状态存储在哪些节点上,由Meld在规则适用时从各个节点收集状态,并相应地更新节点间的状态。此外,当集合状态发生变化时,Meld会自动确定哪些规则不再适用,并恢复它们引起的状态更改,从而为任何Meld程序提供基本的容错行为。
3.4 初步结果
Meld在Claytronics项目中取得了成功。它被用于实现多个复杂应用,包括构建共享坐标系的集合定位程序和形状更改程序。形状更改程序的Meld实现已被证明是正确的,并已在一百万个模拟节点上进行了演示。
3.5 开放问题和预期成果
Meld仍然存在许多缺点,特别是在表达能力方面。Meld缺乏线性或时间组件,这限制了编写具有动态状态的程序的能力。由于模块可能随时移动,可能会阻止在给定时间推导某些事实,并且之后也没有明显的方法推导它们,因此不清楚如何在Meld中实现时间组件。考虑到Meld自动维护状态的方式,添加线性组件同样具有挑战性。Meld会随着物理世界观察状态的变化自动推导和撤销事实,不清楚这如何扩展到线性事实。
有兴趣探索在Meld中支持这些功能的方法。在尝试实现具有动态状态的算法时发现,Meld在这方面不太实用。找到解决方案将大大提高Meld在对集合进行编程时的实用性,因为这将允许高效实现常见类型的算法,如梯度下降算法。除了解决这些问题,还对其他增强Meld的方法感兴趣。
3.6 性能对比
| 数据结构 | 性能表现 | 空间占用 | 适用场景 |
|---|---|---|---|
| 有序列表 | 以列表存储状态时系统性能不可行 | 较大 | 简单场景,对性能要求不高 |
| 物化状态字典树 | 性能较好,但选择性物化会增加计算负担 | 适中 | 状态访问频繁,需要快速查找 |
| 哈希增量函数索引 | 可提高状态索引效率 | 适中 | 状态更新频繁,需要快速索引 |
| 日志字典树和全局状态字典树 | 性能提升明显,几秒内可完成操作 | 较小 | 大规模状态管理,对空间要求较高 |
4 技术对比与总结
4.1 不同逻辑编程技术对比
| 技术名称 | 适用场景 | 主要优势 | 主要挑战 |
|---|---|---|---|
| SLG - WAM中的增量答案完成 | 处理需要答案完成操作的逻辑程序,如包含特定循环结构的程序 | 能分离WFS的非线性,优化后适用于通用编程;初步性能结果显示额外开销可控 | 最坏情况下复杂度较高,为 $atoms(P) × size(P)$ |
| 事务逻辑程序的表列评估 | 涉及状态更新和事务处理的逻辑编程,如人工智能规划、图算法等 | 解决了传统反向链算法的效率问题,通过记忆化和表列技术提高性能 | 空间问题较突出,数据结构的选择和优化难度大 |
| 大规模分布式系统的逻辑编程(Meld语言) | 大规模分布式系统编程,如Claytronics项目 | 让程序员专注逻辑,自动处理状态收集和更新,提供基本容错行为 | 表达能力有限,缺乏线性和时间组件 |
4.2 关键技术流程总结
以下是几种技术的关键流程对比:
graph LR;
classDef startend fill:#F5EBFF,stroke:#BE8FED,stroke-width:2px;
classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px;
classDef decision fill:#FFF6CC,stroke:#FFBC52,stroke-width:2px;
A([开始SLG - WAM评估]):::startend --> B{是否需要答案完成}:::decision;
B -- 否 --> C(在 $O(size(P))$ 内评估):::process;
B -- 是 --> D(迭代应用答案完成操作):::process;
D --> E(检查支持性并简化):::process;
E --> F([结束评估]):::startend;
G([开始事务逻辑表列评估]):::startend --> H{调用是否在表中}:::decision;
H -- 是 --> I(使用表中答案和返回状态):::process;
H -- 否 --> J(插入调用到表中):::process;
J --> K(使用SLD解析程序子句):::process;
K --> L(推导答案):::process;
L --> M(插入答案到表中):::process;
M --> N(返回答案给等效先前调用):::process;
N --> O([结束评估]):::startend;
P([开始Meld编程]):::startend --> Q(编写规则改变集合状态):::process;
Q --> R(自动收集和更新状态):::process;
R --> S{状态是否变化}:::decision;
S -- 是 --> T(更新程序状态):::process;
S -- 否 --> U(继续执行):::process;
T --> U;
U --> V([结束编程]):::startend;
4.3 操作步骤总结
4.3.1 SLG - WAM增量答案完成操作步骤
- 对程序进行评估,判断是否需要答案完成。
- 若不需要,在 $O(size(P))$ 时间内完成评估。
-
若需要,执行ITERATE ANSWER COMPLETION算法:
-
将
reached fixed point设为FALSE。 -
进入循环,只要
reached fixed point为FALSE:-
将
reached fixed point设为TRUE。 - 遍历完成栈中的每个子目标 $S$。
-
对于子目标 $S$ 的每个答案 $A$,调用
Check Supported Answer(A)检查支持性。 -
若答案 $A$ 无支持:
-
将
reached fixed point设为FALSE。 - 删除答案 $A$。
- 传播 $A$ 删除后的简化操作。
-
将
-
将
-
将
- 完成评估。
4.3.2 事务逻辑表列评估操作步骤
- 开始查询,检查调用是否在表中。
- 若在表中,使用表中的答案和返回状态。
-
若不在表中:
- 将调用插入表中。
- 使用类似SLD的解析方法对程序子句进行解析。
- 推导答案。
- 将答案插入与调用关联的表条目。
- 返回答案给查找表中存储的所有等效先前调用。
- 判断是否还有查询,若有则重复上述步骤,若无则结束评估。
4.3.3 Meld编程操作步骤
- 编写规则,根据当前状态更改集合状态。
- Meld自动从各个节点收集状态,并相应地更新节点间的状态。
-
检查集合状态是否变化:
- 若变化,自动确定哪些规则不再适用,并恢复它们引起的状态更改。
- 若未变化,继续执行。
- 结束编程。
5 未来展望
5.1 SLG - WAM的发展方向
虽然SLG - WAM中的增量答案完成技术已经取得了一定的成果,但仍有进一步优化的空间。可以研究更高效的算法来减少最坏情况下的复杂度,例如探索更智能的正循环检测方法,避免不必要的答案完成操作。此外,还可以结合其他优化技术,如并行计算,进一步提高评估效率。
5.2 事务逻辑表列评估的改进
事务逻辑表列评估中的空间问题是一个亟待解决的挑战。未来可以研究更高效的数据结构来存储状态,或者探索新的状态表示方法,以减少空间占用。同时,可以进一步优化状态的查询和更新操作,提高系统的整体性能。对于并发事务逻辑程序的表列技术,需要将其从命题逻辑程序扩展到谓词情况,以扩大其应用范围。
5.3 Meld语言的增强
Meld语言在表达能力方面存在不足,特别是缺乏线性和时间组件。未来可以探索如何在Meld中添加这些组件,例如设计新的语法和语义规则来支持动态状态的表达。同时,可以研究如何在保证自动状态维护的前提下,实现线性事实的推导和管理。此外,还可以进一步增强Meld的容错能力和可扩展性,以满足大规模分布式系统编程的需求。
5.4 跨技术融合
考虑将不同的逻辑编程技术进行融合,发挥各自的优势。例如,将SLG - WAM的答案完成技术与事务逻辑表列评估相结合,用于处理更复杂的逻辑程序;或者将Meld语言的分布式编程理念与事务逻辑相结合,开发出更强大的分布式事务处理系统。通过跨技术融合,可以为逻辑编程在更多领域的应用提供支持。
超级会员免费看

被折叠的 条评论
为什么被折叠?



