Algorithm 替代系统

Algorithm 替代系统,algorithm,text,Algorithm,Text,我目前正在开发一个具有一些功能的高级文本编辑器 其中一个特点是替代系统。它将帮助用户快速替换字符串。 其格式如下: ((a x) | x) (d e) 我们可以将字符串分为两部分:左((ax)| x)和右(de)。如果在|之后有一个字母(x,在当前情况下),那么我们可以执行一个替换操作-将左侧的所有x替换为右侧的字符串。 因此,在操作之后,我们将收到(a(de)) 当然,这些括号内的表达式可能是嵌套的:((a | a)(dx | d))(ef | f)->((ef | f)x)->(ex) 不

我目前正在开发一个具有一些功能的高级文本编辑器

其中一个特点是替代系统。它将帮助用户快速替换字符串。
其格式如下:

((a x) | x) (d e)
我们可以将字符串分为两部分:左
((ax)| x)
和右
(de)
。如果在
|
之后有一个字母(
x
,在当前情况下),那么我们可以执行一个替换操作-将左侧的所有
x
替换为右侧的字符串。
因此,在操作之后,我们将收到
(a(de))

当然,这些括号内的表达式可能是嵌套的:
((a | a)(dx | d))(ef | f)
->
((ef | f)x)
->
(ex)

不幸的是,这种减少可能会无限期地继续下去:
(aaa)(aaa)

我需要显示一个警告,如果用户要编写一个字符串,则无法将其缩减为没有缩减的表单。

有什么建议吗?

祝贺你,你刚刚发明了(发音为“Lambda演算”)

为什么这个问题很难解决 让我们使用原始的符号,因为它已经在20世纪30年代由Church发明:

((λx.f)u)
是对
f
的重写,其中所有
x
已被
u
替换。 请注意,这相当于表示法
(f | x)u
,其中
f
是可以包含
x
的字符串。它是一种数学工具,用来理解什么函数是“可计算的”,也就是说,可以给计算机一个适当的程序,这样对于所有的输入,计算机将运行其程序并输出正确的答案。扰流板:可计算函数正是可以写成λ-项的函数(即在设置中重写)

有时λ-项可以简化,正如您自己所指出的。比如说

(λx.yx)(λu.uu)(λz.z)i)
->
(λx.yx)(λz.z)i)
->
(λx.yx)(λz.z)i
->
(λx.yx)i
->
yi

有时,简化的顺序(也称为“评估”或“贝塔缩减”)是无限的。一个非常著名的是欧米茄算符
(λx.xx)(λx.xx)
(敲钟?)

理想情况下,我们希望限制λ-演算,以便所有术语在有限的步骤中“可简化”为最终可用形式。此属性称为“规范化”。然而,我们真正想要的是更进一步的一步:我们希望所有的简化序列都以最终形式结束在有限数量的步骤中,这样当面临多项选择时,您可以选择其中一项,而不会因为错误的选择而陷入无限循环。这被称为“强规范化”

问题是:λ演算不是强规范化的。这个属性根本不是真的。有些术语最终不会以“正常”形式结束。 你自己也找到了

这个问题在理论上是如何解决的

获得强归一化性质的关键是排除不满足这个性质的矩形项(打印警告并在您的情况下吐出错误),因此我们只考虑强正规化的α-项。这个“排除”是通过一个键入系统实现的:具有有效类型的λ-项是强规范化的,而不具有强规范化的λ-项不能具有有效类型。太棒了,现在我们知道哪些人应该出错了!让我们用简单的例子来验证一下

从你能够非常清楚地表达你的问题的方式来看,我假设你已经有编程和静态类型系统的经验,但是如果你想有一个完整的解释,我可以修改这个答案。我将对类型使用类似Caml的表示法,因此
s
是一个字符串,
s->s
是一个与字符串相关联的函数,
s->(s->s)
是一个与字符串相关联的函数,等等。当变量
x
具有类型
t
时,我表示
x:t

λx.ax:s->s
提供
a:s->s

(λx.yx)((λu.uu)(λz.z)i):s
提供了
y:s->s,i:s
,正如我们从上述减少中看到的那样

λx.x:s->s
。但是要注意,
λx.x:(s->s)->(s->s)
也是正确的。确定类型很难

如何通过编程解决此问题 您的问题稍微容易一些,因为您只处理字符串替换,所以您知道所有内容的基本类型都是字符串,您可以尝试“向上键入”,直到您能够键入整个重写(即没有错误),或者能够证明重写不可键入(请参阅Omega)并抛出错误。但要注意:不能键入重写并不意味着不能键入重写

在您的示例
(λx.ax)(de)
中,您知道
a
d
e
的实际值,因此您可能有例如
a:s->s
d:s->s
e:s
,因此,
de:s
λx.ax:s->s
所以整个东西都有类型
s
,你可以走了。您可能会编写一个编译器,尝试键入重写,并根据一组精心编制的决策规则确定它是否可键入,以满足您的特定用途。您甚至可以决定,如果编译器未能键入重写,那么它将被拒绝(即使它是有效的),因为在一个合理的编辑器文本替换场景中,情况非常复杂,即使正确也会失败

你想用程序解决这个问题吗? 不,我是认真的。你真的不想

记住,λ-项描述所有可计算函数。 如果您真的要实现一个完全正确的警告生成器