Loops 数学确定性自动机

Loops 数学确定性自动机,loops,wolfram-mathematica,deterministic,automaton,Loops,Wolfram Mathematica,Deterministic,Automaton,我想在mathematica中创建一个模块,如果自动机是确定性的或不是确定性的,则返回该模块。 我认为,如果有两个转换以相同的状态开始并读取相同的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

我想在mathematica中创建一个模块,如果自动机是确定性的或不是确定性的,则返回该模块。 我认为,如果有两个转换以相同的状态开始并读取相同的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是一个自动机,其中第一个元素是状态列表,第二个是字母表,第三个是转换,第四个是初始状态,第五个是最终状态列表

主要的问题是,当我将函数应用于一个对象时,它永远不会结束

编辑: 解决

这是最终代码:

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
试试这个

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
 ]

我讨厌看到人们在Mathematica中编写循环,它们几乎总是不必要的,而且几乎在所有情况下都有更好的替代方案,更好的是执行速度更快,更容易编写和理解。这种写作和理解的简易性只有在按照Mathematica设计的方式进行工作时才能体现出来,但如果你继续以命令式的方式编程,你就永远无法做到这一点

好了,说教够了,讲点数学吧。我将首先定义一个非确定性的自动机

aub={{1,2,3},{a,b},{1,a,2},{2,b,1},{2,b,3},1,{2}

在确定自动机决定论的规则的第一个子句中,首先将转换集按其前2个元素分组。表情

GatherBy[aub[[3]],{First[],First[Rest[]}&]

产生输出

{{{1,a,2}},{{2,b,1},{2,b,3}}

如果仔细检查,你会发现这是一个列表列表,每个列表都是前两个元素开始状态和事件匹配的转换列表。现在只需检查这些列表的长度:

映射[长度[]==1&, GatherBy[aub[[3]],{First[],First[Rest[]}&]]

生成列表

{对,错}

最后,将最后一个表达式的开头改为And,我们得到

和@@Map[Length[]==1&, GatherBy[aub[[3]],{First[],First[Rest[]}&]]

这就是答案

假的

接下来,确定决定论规则的第二条要求不存在空的转换。我不确定您将如何对这些进行建模,我将假设这样的转换看起来像{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]], {}]]
以取代基于循环的方法


或者你可以随意忽略这些无缘无故的建议

谢谢你的回答!现在没有无限循环,但当它应该显示TrueWell时,它显示False,非常感谢大家。最后,我解算了逻辑部分,只是给j加了一个1。我将编辑以显示最终代码。一个我很难发现的错误是模块中的大写字母。酷!我喜欢。我使用For是因为我习惯于用C/C++、Java和ASM编程。我很难改变主意。无论如何,我会从你的代码中学到很多。谢谢