我想在mathematica中创建一个模块,如果自动机是确定性的,则返回该模块。 我正在考虑如果有2个转换从相同的状态开始并读取相同的simbol,或者如果存在空转换,则自动机不是确定性的。
我想调试这段代码,但我不能:
isDeterministic[au_] := Module[{a, s},
For[i = 1, i <= Length[au[[3]]],
a = au[[3]][[i]][[1]];
s = au[[3]][[i]][[2]];
If[s == {}, Return[False]];
For[j = i, j <= Length[au[[3]]],
If[a == au[[3]][[j]][[1]] && s == au[[3]][[j]][[2]],
Return[False]];
j++;
];
i++;
];
Return[True];
]
A = {{1, 2},
{a, b},
{{1, a, 2}, {2, b, 1}},
1,
{2}
}
isDeterministic[A]
A是一个自动机,其中第一个元素是状态列表,第二个是字母表,第三个是转换,第四个是初始状态,第五个是最终状态列表。
主要问题是,当我将函数应用于A时,它永远不会结束。
编辑: 解决
这是最终的代码:
isDeterministic[au_] :=
Module[{a, s, lambda},
For[i = 1, i <= Length[au[[3]]], i++, a = au[[3]][[i]][[1]];
s = au[[3]][[i]][[2]];
If[s == lambda, Return[False]];
For[j = i + 1, j <= Length[au[[3]]], j++,
If[a == au[[3]][[j]][[1]] && s == au[[3]][[j]][[2]],
Return[False]]]];
True]
A = {{1, 2},
{a, b},
{{2, b, 1}, {1, a, 2}},
1,
{2}
}
isDeterministic[A]
True
答案 0 :(得分:1)
试试这个
isDeterministic[au_]:=Module[{a,s,len = Length[au[[3]]] },
For[i = 1, i <= len, i++,
a=au[[3]][[i]][[1]];
s=au[[3]][[i]][[2]];
If[s=={}, Return[False,Module] ];
For[j = i, j <= len, j++,
If[a==au[[3]][[j]][[1]]&&s==au[[3]][[j]][[2]],
Return[False,Module]
]
]
];
True
]
答案 1 :(得分:1)
我讨厌看到人们在Mathematica中编写循环,他们几乎总是不必要的,并且几乎在所有情况下都有更好的选择,更好的是执行速度更快,更易于编写和理解。这种易于编写和理解的一部分只有Mathematica设计使用的方式经验,但如果继续以命令式方式编程,你永远不会得到它。
好吧,足够的,在一些Mathematica上。我将首先定义一个非确定性的自动机
aub = {{1, 2, 3}, {a, b}, {{1, a, 2}, {2, b, 1}, {2, b, 3}}, 1, {2}};
使用规则的第一个子句来确定自动机的确定性,首先按前两个元素对转换集进行分组。表达式
GatherBy[aub[[3]], {First[#], First[Rest[#]]} &]
产生输出
{{{1, a, 2}}, {{2, b, 1}, {2, b, 3}}}
如果你仔细研究一下,你会发现这是一个列表列表,每个列表都是前两个元素(开始状态和事件)匹配的转换列表。现在检查这些列表的长度很简单:
Map[Length[#] == 1 &,
GatherBy[aub[[3]], {First[#], First[Rest[#]]} &]]
生成列表
{True, False}
最后,将最后一个表达式的头部改为And
,我们得到
And @@ Map[Length[#] == 1 &,
GatherBy[aub[[3]], {First[#], First[Rest[#]]} &]]
给出了回复
False
接下来,确定确定性的规则的第二个条款要求没有空转换。我不确定你将如何对这些进行建模,我认为这样的转换看起来像{1,{},2}
,一个带有空事件列表的开始和结束状态。我需要另一个测试用例
auc = {{1, 2}, {a, b}, {{1, a, 2}, {2, {}, 1}, {2, b, 1}}, 1, {2}};
要检查这一点,首先从过渡中获取所有事件的集合:
auc[[3, ;; , 2]]
返回
{a, {}, b}
我使用;;
表示法对切换数组进行切片,并仅从中选择事件。然后
FreeQ[auc[[3, ;; , 2]], {}]
检查空列表是否在转换的切片中。当然,在这种情况下,表达式返回False
。
所以,我建议使用函数
isDeterministic[au_]:=And[(And @@
Map[Length[#] == 1 &,
GatherBy[au[[3]], {First[#], First[Rest[#]]} &]]),
FreeQ[au[[3, ;; , 2]], {}]]
替换基于循环的方法。
或者随意忽略这个无偿的建议。