Advertisement
honey_the_codewitch

minimize c#

Nov 1st, 2024
140
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 7.05 KB | None | 0 0
  1. static void _Init<T>(IList<T> list, int count)
  2. {
  3.     for (int i = 0; i < count; ++i)
  4.     {
  5.         list.Add(default(T));
  6.     }
  7. }
  8. static FA _Minimize(FA a, IProgress<int> progress)
  9. {
  10.     int prog = 0;
  11.     progress?.Report(prog);
  12.  
  13.     a = a.ToDfa(progress);
  14.     var tr = a._transitions;
  15.     if (1 == tr.Count)
  16.     {
  17.         FATransition t = tr[0];
  18.         if (t.To == a && t.Min == 0 && t.Max == 0x10ffff)
  19.         {
  20.             return a;
  21.         }
  22.     }
  23.  
  24.     a.Totalize();
  25.     ++prog;
  26.     progress?.Report(prog);
  27.     // Make arrays for numbered states and effective alphabet.
  28.     var cl = a.FillClosure();
  29.     var states = new FA[cl.Count];
  30.     int number = 0;
  31.     foreach (var q in cl)
  32.     {
  33.         states[number] = q;
  34.         q._MinimizationTag = number;
  35.         ++number;
  36.     }
  37.  
  38.     var pp = new List<int>();
  39.     for (int ic = cl.Count, i = 0; i < ic; ++i)
  40.     {
  41.         var ffa = cl[i];
  42.         pp.Add(0);
  43.         foreach (var t in ffa._transitions)
  44.         {
  45.             pp.Add(t.Min);
  46.             if (t.Max < 0x10ffff)
  47.             {
  48.                 pp.Add((t.Max + 1));
  49.             }
  50.         }
  51.     }
  52.  
  53.     var sigma = new int[pp.Count];
  54.     pp.CopyTo(sigma, 0);
  55.     Array.Sort(sigma);
  56.  
  57.     // Initialize data structures.
  58.     var reverse = new List<List<Queue<FA>>>();
  59.     foreach (var s in states)
  60.     {
  61.         var v = new List<Queue<FA>>();
  62.         _Init(v, sigma.Length);
  63.         reverse.Add(v);
  64.     }
  65.     prog = 2;
  66.     if (progress != null) { progress.Report(prog); }
  67.     var reverseNonempty = new bool[states.Length, sigma.Length];
  68.  
  69.     var partition = new List<LinkedList<FA>>();
  70.     _Init(partition, states.Length);
  71.     ++prog;
  72.     if (progress != null) { progress.Report(prog); }
  73.     var block = new int[states.Length];
  74.     var active = new _FList[states.Length, sigma.Length];
  75.     var active2 = new _FListNode[states.Length, sigma.Length];
  76.     var pending = new Queue<KeyValuePair<int, int>>();
  77.     var pending2 = new bool[sigma.Length, states.Length];
  78.     var split = new List<FA>();
  79.     var split2 = new bool[states.Length];
  80.     var refine = new List<int>();
  81.     var refine2 = new bool[states.Length];
  82.  
  83.     var splitblock = new List<List<FA>>();
  84.     _Init(splitblock, states.Length);
  85.     ++prog;
  86.     progress?.Report(prog);
  87.     for (int q = 0; q < states.Length; q++)
  88.     {
  89.         splitblock[q] = new List<FA>();
  90.         partition[q] = new LinkedList<FA>();
  91.         for (int x = 0; x < sigma.Length; x++)
  92.         {
  93.             reverse[q][x] = new Queue<FA>();
  94.             active[q, x] = new _FList();
  95.         }
  96.     }
  97.  
  98.     // Find initial partition and reverse edges.
  99.     foreach (var qq in states)
  100.     {
  101.         int j = qq.IsAccepting ? 0 : 1;
  102.  
  103.         partition[j]?.AddLast(qq);
  104.         block[qq._MinimizationTag] = j;
  105.         for (int x = 0; x < sigma.Length; x++)
  106.         {
  107.             var y = sigma[x];
  108.             var p = qq._Step(y);
  109.             System.Diagnostics.Debug.Assert(p != null);
  110.             var pn = p._MinimizationTag;
  111.             reverse[pn]?[x]?.Enqueue(qq);
  112.             reverseNonempty[pn, x] = true;
  113.         }
  114.         ++prog;
  115.         progress?.Report(prog);
  116.     }
  117.  
  118.     // Initialize active sets.
  119.     for (int j = 0; j <= 1; j++)
  120.     {
  121.         for (int x = 0; x < sigma.Length; x++)
  122.         {
  123.             var part = partition[j];
  124.             System.Diagnostics.Debug.Assert(part != null);
  125.             foreach (var qq in part)
  126.             {
  127.                 System.Diagnostics.Debug.Assert(qq != null);
  128.                 if (reverseNonempty[qq._MinimizationTag, x])
  129.                 {
  130.                     active2[qq._MinimizationTag, x] = active[j, x].Add(qq);
  131.                 }
  132.             }
  133.         }
  134.         ++prog;
  135.         progress?.Report(prog);
  136.     }
  137.  
  138.     // Initialize pending.
  139.     for (int x = 0; x < sigma.Length; x++)
  140.     {
  141.         int a0 = active[0, x].Count;
  142.         int a1 = active[1, x].Count;
  143.         int j = a0 <= a1 ? 0 : 1;
  144.         pending.Enqueue(new KeyValuePair<int, int>(j, x));
  145.         pending2[x, j] = true;
  146.     }
  147.  
  148.     // Process pending until fixed point.
  149.     int k = 2;
  150.     while (pending.Count > 0)
  151.     {
  152.         KeyValuePair<int, int> ip = pending.Dequeue();
  153.         int p = ip.Key;
  154.         int x = ip.Value;
  155.         pending2[x, p] = false;
  156.  
  157.         // Find states that need to be split off their blocks.
  158.         for (var m = active[p, x].First; m != null; m = m.Next)
  159.         {
  160.             System.Diagnostics.Debug.Assert(m.State != null);
  161.             foreach (var s in reverse[m.State._MinimizationTag][x])
  162.             {
  163.                 if (!split2[s._MinimizationTag])
  164.                 {
  165.                     split2[s._MinimizationTag] = true;
  166.                     split.Add(s);
  167.                     int j = block[s._MinimizationTag];
  168.                     splitblock[j]?.Add(s);
  169.                     if (!refine2[j])
  170.                     {
  171.                         refine2[j] = true;
  172.                         refine.Add(j);
  173.                     }
  174.                 }
  175.             }
  176.         }
  177.         ++prog;
  178.         if (progress != null) { progress.Report(prog); }
  179.         // Refine blocks.
  180.         foreach (int j in refine)
  181.         {
  182.             if (splitblock[j]?.Count < partition[j]?.Count)
  183.             {
  184.                 LinkedList<FA> b1 = partition[j];
  185.                 System.Diagnostics.Debug.Assert(b1 != null);
  186.                 LinkedList<FA> b2 = partition[k];
  187.                 System.Diagnostics.Debug.Assert(b2 != null);
  188.                 var e = splitblock[j];
  189.                 System.Diagnostics.Debug.Assert(e != null);
  190.                 foreach (var s in e)
  191.                 {
  192.                     b1.Remove(s);
  193.                     b2.AddLast(s);
  194.                     block[s._MinimizationTag] = k;
  195.                     for (int c = 0; c < sigma.Length; c++)
  196.                     {
  197.                         _FListNode sn = active2[s._MinimizationTag, c];
  198.                         if (sn != null && sn.StateList == active[j, c])
  199.                         {
  200.                             sn.Remove();
  201.                             active2[s._MinimizationTag, c] = active[k, c].Add(s);
  202.                         }
  203.                     }
  204.                 }
  205.  
  206.                 // Update pending.
  207.                 for (int c = 0; c < sigma.Length; c++)
  208.                 {
  209.                     int aj = active[j, c].Count;
  210.                     int ak = active[k, c].Count;
  211.                     if (!pending2[c, j] && 0 < aj && aj <= ak)
  212.                     {
  213.                         pending2[c, j] = true;
  214.                         pending.Enqueue(new KeyValuePair<int, int>(j, c));
  215.                     }
  216.                     else
  217.                     {
  218.                         pending2[c, k] = true;
  219.                         pending.Enqueue(new KeyValuePair<int, int>(k, c));
  220.                     }
  221.                 }
  222.  
  223.                 k++;
  224.             }
  225.             var sbj = splitblock[j];
  226.             System.Diagnostics.Debug.Assert(sbj != null);
  227.             foreach (var s in sbj)
  228.             {
  229.                 split2[s._MinimizationTag] = false;
  230.             }
  231.  
  232.             refine2[j] = false;
  233.             //splitblock[j].Clear();
  234.             sbj.Clear();
  235.             ++prog;
  236.             if (progress != null) { progress.Report(prog); }
  237.         }
  238.  
  239.         split.Clear();
  240.         refine.Clear();
  241.     }
  242.     ++prog;
  243.     if (progress != null) { progress.Report(prog); }
  244.     // Make a new state for each equivalence class, set initial state.
  245.     var newstates = new FA[k];
  246.     for (int n = 0; n < newstates.Length; n++)
  247.     {
  248.         var s = new FA();
  249.         s.IsDeterministic = true;
  250.         newstates[n] = s;
  251.         var pn = partition[n];
  252.         System.Diagnostics.Debug.Assert(pn != null);
  253.         foreach (var q in pn)
  254.         {
  255.             if (q == a)
  256.             {
  257.                 a = s;
  258.             }
  259.             s.Id = q.Id;
  260.             s.AcceptSymbol = q.AcceptSymbol;
  261.             s._MinimizationTag = q._MinimizationTag; // Select representative.             
  262.             q._MinimizationTag = n;
  263.         }
  264.         ++prog;
  265.         progress?.Report(prog);
  266.     }
  267.  
  268.     // Build transitions and set acceptance.
  269.     foreach (var s in newstates)
  270.     {
  271.         var st = states[s._MinimizationTag];
  272.         s.AcceptSymbol = st.AcceptSymbol;
  273.         foreach (var t in st._transitions)
  274.         {
  275.             s._transitions.Add(new FATransition(newstates[t.To._MinimizationTag], t.Min, t.Max));
  276.         }
  277.         ++prog;
  278.         progress?.Report(prog);
  279.     }
  280.     // remove dead transitions
  281.     foreach (var ffa in a.FillClosure())
  282.     {
  283.         var itrns = new List<FATransition>(ffa._transitions);
  284.         foreach (var trns in itrns)
  285.         {
  286.             if (null == trns.To.FindFirst(AcceptingFilter))
  287.             {
  288.                 ffa._transitions.Remove(trns);
  289.             }
  290.         }
  291.     }
  292.     return a;
  293. }
  294. FA _Step(int input)
  295. {
  296.     for (int ic = _transitions.Count, i = 0; i < ic; ++i)
  297.     {
  298.         var t = _transitions[i];
  299.         if (t.Min <= input && input <= t.Max)
  300.             return t.To;
  301.  
  302.     }
  303.     return null;
  304. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement