这可能是一个哲学/基本问题,但我只想澄清一下。
在我的理解中,有限状态机是一种对系统建模的方式,其中系统的输出不仅取决于当前的输入,而且还取决于系统的当前状态。另外,顾名思义,可以将有限状态机及其各自的状态和行为划分为有限的N个状态。
如果这是正确的,难道不是每个带有数据和函数成员的对象都是我们的面向对象模型中的一个状态,从而使任何面向对象的设计成为有限状态机吗?
如果这不是对象设计中FSM的解释,那么人们在软件中实现FSM时到底意味着什么?我错过了什么吗?
谢谢
这可能是一个哲学/基本问题,但我只想澄清一下。
在我的理解中,有限状态机是一种对系统建模的方式,其中系统的输出不仅取决于当前的输入,而且还取决于系统的当前状态。另外,顾名思义,可以将有限状态机及其各自的状态和行为划分为有限的N个状态。
如果这是正确的,难道不是每个带有数据和函数成员的对象都是我们的面向对象模型中的一个状态,从而使任何面向对象的设计成为有限状态机吗?
如果这不是对象设计中FSM的解释,那么人们在软件中实现FSM时到底意味着什么?我错过了什么吗?
谢谢
Answers:
在具有有限存储量的计算机上运行的任何单线程程序都可以建模为有限状态机。有限状态机中的特定状态将代表所有相关存储的特定值-局部变量,全局变量,堆存储,虚拟内存中当前换出的数据,甚至相关文件的内容。换句话说,即使对于非常琐碎的程序,该有限状态模型中也会有很多状态。
即使您的程序只有一个状态是32位整数类型的单个全局变量,也意味着至少2 ^ 32(超过40亿)个状态。而且这甚至都没有考虑到程序计数器和调用堆栈。
下推式自动机模型对于这种情况更为现实。它就像一个有限的自动机,但是有一个内置的堆栈概念。但是,它实际上并不是大多数编程语言中的调用堆栈。
有Wikipedia的说明,但请不要在正式定义部分中迷惑了。
下推自动机用于对通用计算进行建模。图灵机相似,但IIRC不同-尽管它们的计算能力是等效的。
谢谢kevin cline指出了上述错误-正如Wikipedia所指出的那样,下推自动机比有限状态机更强大,但不比图灵机更强大。
老实说,我不知道这种大脑放屁的来源-我确实知道上下文敏感的语法比上下文无关的语法更强大,并且上下文敏感的语法无法使用简单的下推自动机进行解析。我什至知道,尽管可以在线性时间内解析任何明确的上下文无关文法,但通常这样做不仅仅需要一个(确定性)下推自动机。因此,我最终如何相信下推式自动机等同于图灵机是奇怪的。
也许我在考虑添加了一些额外机械的下推式自动机,但这就像将有限的自动机算作下推式自动机一样(只需添加并利用堆栈)。
下推自动机在解析中很重要。在这种情况下,我对它们足够熟悉,但是我从来没有真正将它们作为计算机科学计算模型进行研究,因此我无法提供比我已有的更多细节。
可以将单个OOP对象建模为有限状态机。机器的状态将由所有成员变量的状态决定。通常,您只会在方法调用之间(而不是在方法调用之间)计算有效状态。同样,您通常会担心很多状态,您可以将其用作理论模型,但是除了小规模情况外,您不想列举所有这些状态。
但是,使用有限状态机来建模对象状态的某些方面是相当普遍的。常见的情况是游戏对象使用AI。
这也是使用下推自动机模型定义解析器时通常要做的事情。尽管状态模型中有一组有限的状态,但这仅对解析器状态的一部分进行建模-其他信息与该状态一起存储在额外的变量中。例如,这解决了40亿个一整数状态的问题-不必枚举所有这些状态,只需包含整数变量即可。从某种意义上讲,它仍然是下推自动机状态的一部分,但是,与在图表上实际绘制40亿个状态气泡相比,这是一种更易于管理的方法。
直接回答您的问题:几乎可以肯定。对于OOP而言,似乎没有形式化的数学理论能够像lambda演算和/或组合逻辑在功能性编程下,或者Turing Machines在普通的旧式命令式编程下那样。
有关更多信息,请参见此stackoverflow问题。
我的猜测是,缺乏基本的数学理论,这就是为什么每个人看到一个“物体”时都知道“物体”是什么,却没人能像其他人一样看到“物体”的原因。
不,实际上不行。有限状态机通常只记住一个数据:其当前状态。
FSM的典型应用是词法分析。例如,当我们进行词法化时,(通常)用当前状态和输入值对每个可能的输入的动作进行编码是很容易的。
例如,我们可能处于NUMBER状态,正在读取数字。如果我们读取的下一个字符是数字,则我们将保持NUMBER状态。如果是空格或制表符,我们将返回数字,然后进入某种WHITE_SPACE状态,或按该顺序排列。
现在,可以肯定的是,在典型的FSM(尤其是在软件中实现的FSM)中,我们最终得到的点点滴滴在技术上并不完全适合于与FSM本身混合的FSM。例如,当我们读取一个数字时,您经常会保存第一个数字的位置,因此当到达最后时,您可以轻松地计算数字的值。
FSM本身有一些限制-它没有计数机制。例如,考虑使用“ / ”开始注释和使用“ /”结束注释的语言。它的词法分析器在看到'/ '标记时可能会进入COMMENT状态。在这一点上,它没有办法(缺少添加像COMMENT2这样的另一个状态)来检测另一个“ / ”并意识到它正在处理嵌套的注释。相反,在注释状态下,它将被识别*/
为告诉其退出注释状态,而其他任何事情都会使其处于注释状态。
如前所述,您当然可以包括用于嵌套注释的COMMENT2状态-以及COMMENT3状态,依此类推。但是,到某个时候,您会厌倦添加更多状态,这将决定允许注释的最大嵌套深度。使用其他形式的解析器(即,不是纯状态机,而是具有一定数量的内存供其使用的解析器),您可以直接跟踪嵌套深度,因此您将一直处于COMMENT状态,直到获得一个接近的注释令牌为止平衡第一个,因此您的计数器回到0,并且退出COMMENT状态。
正如我所说,但是,当您添加这样的计数器时,您拥有的不再是真正的FSM。同时,它是实际上是非常接近-具体而言,足够接近,你可以仅仅通过增加更多的状态模拟计数器。
但是,在典型情况下,当有人谈论在软件中实现FSM时,他们会将其合理地 “纯净”。特别是,软件将仅基于当前状态和输入本身的值对当前输入做出反应。如果反应取决于很多其他因素,那么他们通常不会将其称为状态机(至少如果他们知道他们在说什么)。