using System; using System.Collections.Generic; using M17N; using M17N.Core; public class Test { const int LENGTH = 9; static MText mt = new MText ("012345678"); static MSymbol key = MSymbol.PropertyKey ("rse", MProperty.Flags.RearSensitive); static MSymbol val0 = MSymbol.Of ("0"); static MSymbol val1 = MSymbol.Of ("1"); static MSymbol val2 = MSymbol.Of ("2"); static MProperty prop0 = new MProperty (key, val0); static MProperty prop1 = new MProperty (key, val1); static MProperty prop2 = new MProperty (key, val2); // Each property is identified by its beginning point. // The character at position i has the property that begins at prop[i]. // If the character has no property, prop[i] == -1. static int[] prop = new int[LENGTH]; // The property beginning at position i ends at position end[i]. // If no property begins at position i, end[i] is undefined. static int[] end = new int[LENGTH]; // The property beginning at position i has value value[i]. // If no property begings at positoin i, value[i] is undefined. static MSymbol[] value = new MSymbol[LENGTH]; static void TestPushProp (int from, int to, MProperty newprop) { Console.WriteLine ("from {0}, to {1}, push {2}.\n", from, to, newprop.Val); int i, n; if (from > 0 && prop[from - 1] == prop[from] && prop[from] != -1) { n = end[prop[from]]; for (i = prop[from]; i < n; i++) prop[i] = -1; } if (to < LENGTH && prop[to - 1] == prop[to] && prop[to] != -1) { n = end[prop[to]]; for (i = to; i < n; i++) prop[i] = -1; } for (i = from; i < to; i++) prop[i] = from; end[from] = to; value[from] = (MSymbol) newprop.Val; mt.PushProp (from, to, newprop); } static void TestPopProp (int from, int to, MSymbol key) { Console.WriteLine ("from {0}, to {1}, pop.\n", from, to); int i, n; if (from > 0 && prop[from - 1] == prop[from] && prop[from] != -1) for (i = prop[from]; i < from; i++) prop[i] = -1; if (to < LENGTH && prop[to - 1] == prop[to] && prop[to] != -1) { n = end[prop[to]]; for (i = to; i < n; i++) prop[i] = -1; } for (i = from; i < to; i++) prop[i] = -1; mt.PopProp (from, to, key); } static void TestDelIns (int from, int to, int from2) { Console.WriteLine ("from {0}, to {1}, moveto {2}.\n", from, to, from2); int i, j, n, l = to - from; int[] prop2 = new int[LENGTH], end2 = new int[LENGTH]; MSymbol[] value2 = new MSymbol[LENGTH]; // sensitivity for deletion if (from > 0 && prop[from - 1] != -1) { n = prop[from - 1] == prop[from] ? end[prop[from]] : from; for (i = prop[from - 1]; i < n; i++) prop[i] = -1; } if (to < LENGTH && prop[to - 1] != -1) { n = prop[to - 1] == prop[to] ? end[prop[to]] : to; for (i = prop[to - 1]; i < n; i++) prop[i] = -1; } // copy for (i = from, j = from2; i < to; i++, j++) { if (prop[i] != -1) { prop2[j] = prop[i] - from + from2; end2[j] = end[i] - from + from2; value2[j] = value[i]; } else prop2[j] = -1; } /* Console.Write ("\n "); for (j = from2; j < from2 + l; j++) Console.Write ("{0} ", j); Console.Write ("\n--------------------\nP "); for (j = from2; j < from2 + l; j++) { if (prop2[j] != -1) Console.Write ("{0} ", prop2[j]); else Console.Write (" "); } Console.Write ("\nE "); for (j = from2; j < from2 + l; j++) { if (prop2[j] != -1) Console.Write ("{0} ", end2[j]); else Console.Write (" "); } Console.Write ("\nV "); for (j = from2; j < from2 + l; j++) { if (prop2[j] != -1) Console.Write ("{0} ", value2[j]); else Console.Write (" "); } Console.Write ("\n"); */ // delete for (i = to; i < LENGTH; i++) { if (prop[i] != -1) { prop[i - l] = prop[i] - l; end[i - l] = end[i] - l; value[i - l] = value[i]; } else prop[i - l] = -1; } // sensitivity for insertion if (from2 > 0 && prop[from2 - 1] != -1) { n = prop[from2 - 1] == prop[from2] ? end[prop[from2]] : from2; for (i = prop[from2 - 1]; i < n; i++) prop[i] = -1; } if (from2 + l < LENGTH && prop2[from2 + l - 1] != -1) for (i = prop2[from2 + l -1]; i < from2 + l; i++) prop2[i] = -1; // move for (i = LENGTH - 1; i >= from2 + l; i--) { if (prop[i - l] != -1) { prop[i] = prop[i - l] + l; end[i] = end[i - l] + l; value[i] = value[i - l]; } else prop[i] = -1; } // insert for (i = from2; i < from2 + l; i++) { prop[i] = prop2[i]; if (prop2[i] != -1) { end[i] = end2[i]; value[i] = value2[i]; } } MText mt2 = mt.Dup (); mt.Del (from, to); mt.Ins (from2, mt2, from, to); } static bool Compare () { for (int i = 0; i < LENGTH; i++) { object val = mt.GetProp (i, key); if (prop[i] == -1 && (MSymbol) val != null) { Console.WriteLine ("value[{0}] is nil, GetProp returned {1}", i, val == null ? MSymbol.nil : val); return false; } if (prop[i] != -1 && (value[prop[i]] != (MSymbol) val)) { Console.WriteLine ("value[{0}] is {1}, GetProp returned {2}", i, value[prop[i]] == null ? MSymbol.nil : value[prop[i]], val == null ? MSymbol.nil : val); return false; } } return true; } static void Dump () { for (int i = 0; i <= LENGTH; i++) Console.Write ("{0} ", i); Console.WriteLine ("\n-------------------"); if (prop[0] == -1) Console.Write (" "); else Console.Write ("{0} ", value[prop[0]]); for (int i = 1; i < LENGTH; i++) { if (prop[i] == -1) Console.Write (" "); else if (prop[i - 1] == prop[i]) Console.Write ("< "); else Console.Write ("{0} ", value[prop[i]]); } Console.Write ("\n"); } /* static void DebugDump (int n) { int i; Console.Write ("\n#{0}\n ", n); for (i = 0; i <= LENGTH; i++) Console.Write ("{0} ", i); Console.Write ("\n----------------------\nP "); for (i = 0; i < LENGTH; i++) { if (prop[i] != -1) Console.Write ("{0} ", prop[i]); else Console.Write (" "); } Console.Write ("\nE "); if (prop[0] != -1) Console.Write ("{0} ", end[0]); else Console.Write (" "); for (i = 1; i < LENGTH; i++) { if (prop[i - 1] != prop[i] && prop[i] != -1) Console.Write ("{0} ", end[i]); else Console.Write (" "); } Console.Write ("\nV "); if (prop[0] != -1) Console.Write ("{0} ", value[0]); else Console.Write (" "); for (i = 1; i < LENGTH; i++) { if (prop[i - 1] != prop[i] && prop[i] != -1) Console.Write ("{0} ", value[i]); else Console.Write (" "); } Console.Write ("\n"); } */ public static void Main (string[] args) { Random r = new Random (int.Parse (args[0])); int check = (args.Length > 1 ? int.Parse (args[1]) : 0xFFFFFFF); for (int i = 0; i < LENGTH; i++) prop[i] = -1; for (int loop = 0; loop < 1000000; loop++) { int from, to; Console.WriteLine ("--- loop = {0} ---\n", loop); if (loop >= check) { mt.DumpPropNested (); Dump (); M17n.debug = true; } do { from = r.Next (LENGTH); to = r.Next (LENGTH) + 1; } while (from == to); if (from > to) { int tmp = from; from = to; to = tmp; } MProperty prop; switch (r.Next (3)) { case 0: prop = prop0; break; case 1: prop = prop1; break; default: prop = prop2; break; } switch (r.Next (3)) { case 0: TestPushProp (from, to, prop); break; case 1: TestPopProp (from, to, key); break; case 2: TestDelIns (from, to, r.Next (LENGTH - (to - from) + 1)); break; } if (M17n.debug) mt.DumpPropNested (); if (Compare () == false) { Console.WriteLine (""); Dump (); Console.WriteLine ("Failed."); return; } } } }