您可以使用定句语法 (DCG) 来实现有限状态转换器。尽管 DCG 在制作方面并没有提供太多的合成操作,但它们在识别方面的实现却相当出色。
因此,您要识别的是两种不同类型的 1 运行。所以基本上我猜输入行在扩展巴科斯瑙尔形式(EBNF)中如下所示:
line :== exs run1 exs run2 exs | exs.
exs :== { "x" } "x".
run1 :== { "1" } "1".
run2 :== { "1" } "1".
对于识别问题,你可以写一个不带属性的DCG(下面是一段Prolog文本,你可以放在一个文件中或直接通过?- [user]查阅):
line --> exs, run1, exs, run2, exs | exs.
run1 --> "1", run1.
run1 --> "1".
run2 --> "1", run2.
run2 --> "1".
exs --> "x", exs.
exs --> "x".
以下是一些示例运行:
?- phrase(line,"xxx").
Yes
?- phrase(line,"xxx111xxx111xxx").
Yes
?- phrase(line,"xxx111xxx").
No
对于生产问题,您只需将属性添加到 DCG。使用差异列表最简单:
line(I,O) --> exs(I,H), run1(H,J), exs(J,K), run2(K,L), exs(L,O) | exs(I,O).
run1([0'1|I],O) --> "1", run1(I,O).
run1([0'1|H],H) --> "1".
run2([0'2|I],O) --> "1", run2(I,O).
run2([0'2|H],H) --> "1".
exs([0'x|I],O) --> "x", exs(I,O).
exs([0'x|H],H) --> "x".
以下是一些示例运行:
?- phrase(line(R,[]),"xxx").
R = [120, 120, 120]
?- phrase(line(R,[]),"xxx111xxx111xxx").
R = [120, 120, 120, 49, 49, 49, 120, 120, 120, 50, 50, 50, 120, 120, 120]
?- phrase(line(R,[]),"xxx111xxx").
No
注意:0' 是字符代码的 Prolog 符号。在 ascii 中,我们有 0'x = 120, 0'1 = 49, 0'2 = 50,这解释了结果。以上应该可以在大多数 Prolog 系统上运行,因为它们支持 DCG。
再见
定从句语法
http://en.wikipedia.org/wiki/Definite_clause_grammar
有限状态传感器
http://en.wikipedia.org/wiki/Finite_state_transducer