- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
编辑:用户@apocalisp和@BenjaminHodgson在下面留下了很棒的答案,跳过阅读大部分问题并跳转到他们的答案。
问题的TLDR:我怎样才能从第一张图片(FSM 状态组合爆炸)转到第二张图片(您只需要在继续之前访问所有图片)。
<小时/>我想构建一个有限状态机(实际上是在Haskell中,但我首先尝试Idris,看看它是否可以指导我的Haskell),其中有一些必须访问的临时状态在达到最终状态之前。如果我可以在某些状态上使用谓词任意约束 FSM,那就太好了。
在下图中,有一个 Initial
状态、3 个中间状态 A、B、C
和一个 Final
状态。如果我没记错的话,在“正常”FSM 中,您将始终需要 n!
临时状态来表示可能路径的每种组合。
这是不可取的。
相反,使用类型族,也许依赖类型,我认为应该有可能拥有一种随身携带的状态,并且仅当它通过时某些谓词将允许您进入最终状态。 (这是否使它下推自动机而不是FSM?)
到目前为止,我的代码(idris),以此类推,正在添加成分来制作沙拉,顺序并不重要,但它们都需要将其放入:
data SaladState = Initial | AddingIngredients | ReadyToEat
record SaladBowl where
constructor MkSaladBowl
lettuce, tomato, cucumber : Bool
data HasIngredient : (ingredient : SaladBowl -> Bool) -> (bowl : SaladBowl ** ingredient bowl = True) -> Type where
Bowl : HasIngredient ingredient bowl
data HasIngredients : (ingredients : List (SaladBowl -> Bool))
-> (bowl : SaladBowl ** (foldl (&&) True (map (\i => i bowl) ingredients) = True))
-> Type where
Bowlx : HasIngredients ingredients bowl
data SaladAction : (ty : Type) -> SaladState -> (ty -> SaladState) -> Type where
GetBowl : SaladAction SaladBowl Initial (const Initial)
AddLettuce : SaladBowl -> SaladAction (bowl ** HasIngredient lettuce bowl) st (const AddingIngredients)
AddTomato : SaladBowl -> SaladAction (bowl ** HasIngredient tomato bowl) st (const AddingIngredients)
AddCucumber : SaladBowl -> SaladAction (bowl ** HasIngredient cucumber bowl) st (const AddingIngredients)
MixItUp : SaladBowl -> SaladAction (bowl ** (HasIngredients [lettuce, tomato, cucumber] bowl)) AddingIngredients (const ReadyToEat)
Pure : (res : ty) -> SaladAction ty (state_fn res) state_fn
(>>=) : SaladAction a state1 state2_fn
-> ((res : a) -> SaladAction b (state2_fn res) state3_fn)
-> SaladAction b state1 state3_fn
emptyBowl : SaladBowl
emptyBowl = MkSaladBowl False False False
prepSalad1 : SaladAction SaladBowl Initial (const ReadyToEat)
prepSalad1 = do
(b1 ** _) <- AddTomato emptyBowl
(b2 ** _) <- AddLettuce b1
(b3 ** _) <- AddCucumber b2
MixItUp b3
以及编译器应该出错的反示例程序:
BAD : SaladAction SaladBowl Initial (const ReadyToEat)
BAD = do
(b1 ** _) <- AddTomato emptyBowl
(b2 ** _) <- AddTomato emptyBowl
(b3 ** _) <- AddLettuce b2
(b4 ** _) <- AddCucumber b3
MixItUp b4
BAD' : SaladAction SaladBowl Initial (const ReadyToEat)
BAD' = do
(b1 ** _) <- AddTomato emptyBowl
MixItUp b1
我最终希望“成分”是 Sums 而不是 Bools (data Lettuce = Romaine | Iceberg | Butterhead
),以及更强大的语义,我可以说“你必须首先添加生菜” ,或菠菜,但不能两者兼而有之”。
真的,我感觉完全迷失了,我想我上面的代码已经走向了完全错误的方向......我怎样才能构建这个FSM(PDA?)来排除坏程序?我特别想使用 Haskell 来实现它,也许使用索引 Monad?
最佳答案
索引状态单子(monad)正是这样做的。
常规的 State s
monad 模拟一个状态机(具体来说是一个 Mealy 机),其状态字母表是 s
类型。这种数据类型实际上只是一个函数:
newtype State s a = State { run :: s -> (a, s) }
a -> State s b
类型的函数是一个具有输入字母 a
和输出字母 b
的机器。但它实际上只是一个 (a, s) -> (b, s)
类型的函数。
将一台机器的输入类型和另一台机器的输出类型对齐,我们可以组成两台机器:
(>>=) :: State s a -> (a -> State s b) -> State s b
m >>= f = State (\s1 -> let (a, s2) = run m s1 in run (f a) s2)
换句话说,State s
是一个monad。
但有时(如您的情况),我们需要改变中间状态的类型。这就是索引状态单子(monad)的用武之地。它有两个状态字母表。 IxState i j a
模拟一台机器,其起始状态必须为 i
,结束状态为 j
:
newtype IxState i j a = IxState { run :: i -> (a, j) }
常规的 State s
monad 就相当于 IxState s
。我们可以像编写 State
一样轻松地编写 IxState
。实现与以前相同,但类型签名更通用:
(>>>=) :: IxState i j a -> (a -> IxState j k b) -> IxState i k b
m >>>= f = IxState (\s1 -> let (a, s2) = run m s1 in run (f a) s2)
IxState
并不完全是一个 monad,而是一个索引 monad。
我们现在只需要一种指定状态类型约束的方法。对于沙拉示例,我们想要这样的东西:
mix :: IxState (Salad r) Ready ()
这是一台机器,其输入状态是一些不完整的Salad
,由成分r
组成,其输出状态是Ready
,表明我们的沙拉可以吃了。
使用类型级列表,我们可以这样说:
data Salad xs = Salad
data Ready = Ready
data Lettuce
data Cucumber
data Tomato
空沙拉的配料表是空的。
emptyBowl :: IxState x (Salad '[]) ()
emptyBowl = iput Salad
我们可以将生菜添加到任何沙拉中:
addLettuce :: IxState (Salad r) (Salad (Lettuce ': r)) ()
addLettuce = iput Salad
我们可以对番茄和 cucumber 重复相同的操作。
现在 mix
的类型只需为:
mix :: IxState (Salad '[Lettuce, Cucumber, Tomato]) Ready ()
mix = const Ready
如果我们尝试混合任何未添加生菜
、 cucumber
和番茄
的沙拉,我们会收到类型错误到,按这个顺序。例如。这将是一个类型错误:
emptyBowl >>>= \_ -> addLettuce >>>= \_ -> mix
但理想情况下,我们希望能够以任何顺序添加成分。因此,我们需要对类型级别列表进行限制,要求提供证据证明沙拉中存在某种特定成分:
class Elem xs x
instance {-# OVERLAPS #-} Elem (x ': xs) x
instance Elem xs x => Elem (y ': xs) x
Elem xs x
现在是类型 x
位于类型级列表 xs
中的证据。第一个实例(基本情况)表明 x
显然是 x ': xs
的元素。第二个实例表示,如果类型 x
是 xs
的元素,那么它也是任何类型 y ': xs
的元素 y
。 OVERLAPS
对于确保 Haskell 知道首先检查基本情况是必要的。
以下是完整列表:
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE FlexibleContexts #-}
import Control.Monad.Indexed
import Control.Monad.Indexed.State
data Lettuce
data Tomato
data Cucumber
data Ready = Ready
class Elem xs x
instance {-# OVERLAPS #-} Elem (x ': xs) x
instance Elem xs x => Elem (y ': xs) x
data Salad xs = Salad
emptyBowl :: IxState x (Salad '[]) ()
emptyBowl = iput Salad
addLettuce :: IxState (Salad r) (Salad (Lettuce ': r)) ()
addLettuce = iput Salad
addTomato :: IxState (Salad r) (Salad (Tomato ': r)) ()
addTomato = iput Salad
addCucumber :: IxState (Salad r) (Salad (Cucumber ': r)) ()
addCucumber = iput Salad
mix :: (Elem r Lettuce, Elem r Tomato, Elem r Cucumber)
=> IxState (Salad r) Ready ()
mix = imodify mix'
where mix' = const Ready
x >>> y = x >>>= const y
-- Compiles
test = emptyBowl >>> addLettuce >>> addTomato >>> addCucumber >>> mix
-- Fails with a compile-time type error
fail = emptyBowl >>> addTomato >>> mix
关于haskell - 如何在 Haskell/Idris 中拥有受约束的有限状态机?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47660589/
已关闭。此问题需要 debugging details 。目前不接受答案。 编辑问题以包含 desired behavior, a specific problem or error, and the
我刚刚开始使用 Arduino,对更多高级内容几乎一无所知。这看起来很简单。现在我是一个通常喜欢将两个设备集成在一起的人,所以我想知道我是否可以使用计算机的键盘或连接到 Arduino 板上的两个硬件
Hadoop上是否有支持 vector 机的实现? 我正在寻找使我能够训练然后在Hadoop之上测试SVM模型的代码。 最佳答案 有人正在使用BSP在Apache Hama之上进行实现,该实现基本上是
已关闭。此问题需要 debugging details 。目前不接受答案。 编辑问题以包含 desired behavior, a specific problem or error, and the
我想用 Java 编写一个“智能监视器”,它会在它检测到即将出现的性能问题时发出警报。我的 Java 应用正在将结构化格式的数据写入日志文件: | | 因此,例如,如果我有一个执行时间为 812
我在 Cappuccino 中遇到这种错误 TypeError: Result of expression '_2b' [undefined] is not an object. TypeError:
我想编写一个简单的 bean 机程序。该程序将接受用户输入的球数和槽数,并计算每个球的路径。每个槽中的球数也将打印为直方图。 我尽力让代码保持简短和简洁,但我能做到的最好的长度是 112 行。当我运行
我正在开发一个 Plone 模板。目前我正在对模板实现搜索。模板上有一个表单提交到同一模板,即同一页面。 我需要启用页面的某些部分,即结果 DIV,仅当页面中的表单已提交时。我不确定如何检查页面是否已
我是机器学习的新手。我正在使用 opencv 开源库做一个项目。我的问题是我没有机器学习方面的经验。我从不同的图像中提取了特征并对其进行了评估,现在我想使用 SVM 对这些图像中的对象进行分类,但我不
我有一个来自自定义抽象对象的数据集和一个自定义距离函数。是否有任何好的 SVM 库允许我训练我的自定义对象(不是 2d 点)和我的自定义距离函数? 我在 this similar stackoverf
我正在尝试编写 SVM 或 KNN 程序来对文本文档进行分类。我掌握了两者的概念,但我希望看到一些很好的代码示例,它们专门演示了如何将文本/单词表示为 vector 。有人知道好的教程/文章/讲座/任
我想知道支持 vector 机 (SVM) 对于大型/超大型数据集(5-15M+ 行)具有非线性决策边界(例如高斯核)? 我知道两种特殊的方法:一方面,这个使用随机梯度下降等的调查: http://c
我试图在 Raspberry Pi 中使用 python 控制连续伺服(DF15RSMG),但连续伺服无法停止。代码如下: import RPi.GPIO as GPIO import time
我们在 .net 中有银行项目。在那个项目中我们需要实现存折打印。 - 存折背面会有磁条。 - 当客户将存折插入自助服务终端时,自助服务终端将生成 ISO 8583 信息。 - 为响应此消息,CBS(
我想使用 svm 分类器进行面部表情检测。我知道 opencv 有一个 svm api,但我不知道训练分类器的输入应该是什么。到现在看了很多论文,都是说人脸特征检测后训练分类器。 到目前为止我做了什么
就目前而言,这个问题不适合我们的问答形式。我们希望答案得到事实、引用资料或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the
为了学习 ArchLinux,我在 VirtualBox 机器上安装并使用了 ArchLinux。它运行完美。现在我在我的电脑上安装了 Docker(Windows 环境)。在安装 Docker 的过
我找不到很多相关信息,但是我知道可以通过命令提示符electron-packager .创建一个 Electron 应用。但是,可以通过 Node 快速路由在前端执行它吗? 所以我想做这样的事情: r
我正在使用 MS Visual Studio 2008、OpenCV、C++ 和 SVM 继续我的 OCR 项目。我生成了一个超过 2000 个机印字符样本的数据集。当我用线性核测试时,我总是得到 9
我通过UART接口(interface)(RX-TX,GND-GND)将伺服(TowerPro sg90)连接到32伺服 Controller (this one)。 卖家提供了如何连接和控制我的伺服
我是一名优秀的程序员,十分优秀!