mathematica确定性自动机

时间:2012-11-14 00:17:08

标签: loops wolfram-mathematica deterministic automaton

我想在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

2 个答案:

答案 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]], {}]]

替换基于循环的方法。

或者随意忽略这个无偿的建议。